I'm writing using wsimport to generate a client for a web service, however, when I try to initiate the binding with an Addressing feature, I get the following error:
Exception in thread "main" java.lang.ClassCastException: javax.xml.ws.soap.AddressingFeature cannot be cast to [Ljavax.xml.ws.WebServiceFeature;
I know for a fact that javax.xml.ws.soap.AddressingFeature extends javax.xml.ws.WebServiceFeature, so I'm not sure what's happening. I know you cannot downcast in Clojure, but casting to a parent should work.
From my understanding, objects should be autocast, and if they are not, clojure.core/cast should work, however, both throw an exception.
My code looks something like this:
(-> (com.test.TestAPISOAP.)
(.getTestWSHttpBinding
(javax.xml.ws.soap.AddressingFeature. true true)))
It looks like .getTestWSHttpBinding accepts an array (the [L in [Ljavax.xml.ws.WebServiceFeature), not a single element.
Try creating an array with AddressingFeature as a single element using clojure.core/to-array:
(-> (com.test.TestAPISOAP.)
(.getTestWSHttpBinding
(to-array [(javax.xml.ws.soap.AddressingFeature. true true)])))
Related
I have imported the firestore snapshot and trying to create it's object
(:import [com.google.cloud.firestore
QueryDocumentSnapshot])
(def snapshot1 (QueryDocumentSnapshot.toObject. [:reference "user1" :type "Promotion" :included-scans 100]))
But it compile failed and error is :
Exception in thread "main" java.lang.ClassNotFoundException: QueryDocumentSnapshot.toObject,
Can you please help me to create a new object for that class QueryDocumentSnapshot ?
You can call a constructor like
(QueryDocumentSnapshot. whatever-arguments)
But QueryDocumentSnapshot has no public constructor and looking at the source it can only be instantiated using a static factory method like such:
(QueryDocumentSnapshot/fromDocument firestore timestamp document)
I'm not sure what you're actually trying to achieve here but it doesn't look like you can do what you think you can do to that class.
Okay, after taking your and Joost's answers into consideration, I discovered something rather funny:
Your error message says, that the class QueryDocumentSnapshot.toObject cannot be found. There you have it.
If you want to call a static method, you have to write (class/method args).
For more information on java interop I highly recommend the official documentation: https://clojure.org/reference/java_interop
Also, take Joost's comments on the class itself into consideration.
I have a basic Java interface defined as follows:
public interface Action {
void execute(Metadata var1, Parameter var2);
}
I'm trying to extend it in Clojure but keep getting errors. After importing the class into my namespace, I've tried using reify as follows:
(defn action [action-fn]
(reify Action
(execute [metadata parameter] (action-fn metadata parameter))))
but that throws a compiler illegal argument exception:
CompilerException java.lang.IllegalArgumentException: Can't define method not in interfaces: execute
Next I tried using proxy
(defn action [action-fn]
(proxy [Action] []
(execute [metadata parameter] (action-fn metadata parameter))))
That compiles successfully, and my editor (IntelliJ + Cursive) navigates to the interface definition via a border decoration, but trying to invoke execute on a generate proxy fails:
(.execute (action (fn [_ _] "Test action")))
throws the following:
IllegalArgumentException No matching field found: execute for class
Finally I tried using deftype as follows:
(deftype cljAction [action-fn]
Action
(execute [metadata parameter] (action-fn metadata parameter)))
which throws the same compiler error as for reify, e.g:
CompilerException java.lang.IllegalArgumentException: Can't define method not in interfaces: execute
Trawling through various blog posts and SO answers seems to suggest it's a problem with the arity of arguments, but I'm not sure how to resolve it. What am I doing wrong??
You are missing the this reference from the function. So what you want is this:
(defn action [action-fn]
(reify Action
(execute [this metadata parameter] (action-fn metadata parameter))))
Obviously because you are not using it you can just call it _ or whatever makes the most sense in your opinion. When you are calling the function you want this:
(.execute (action action-fn) metadata parameter)
This differs slightly from when you are implementing a protocol. See https://clojuredocs.org/clojure.core/definterface for more information.
ponzao's answer is correct. But note that Cursive can actually fill in the stubs for you: you can write (reify Action) and then (with the cursor in that form somewhere) choose Code->Generate... and choose to implement methods. Cursive will then fill in the stubs with the correct form. This currently only works when implementing interfaces, not protocols.
I was looking at https://github.com/juxt/dirwatch library. The example from the front page is:
(require '[juxt.dirwatch :refer (watch-dir)])
(watch-dir println (clojure.java.io/file "/tmp"))
That works fine. Let's say the above is executed in REPL:
user=> (watch-dir println (clojure.java.io/file "/tmp"))
#<Agent#16824c93: #<LinuxWatchService sun.nio.fs.LinuxWatchService#17ece9ac>>
Now, I have an agent that will print events when I modify files in /tmp:
{:file #<File /tmp/1>, :count 1, :action :modify}
so all is fine.
I know I can reference the agent by using previous expression references (*1, *2 and *3). However, I don't know how to, without restarting the REPL itself:
Unbind an implicit var created like this - i.e. how to remove the binding completely, so that agent gets GCed and stops working
Access it in case I lost it in cases where I did not bind it, such as the above. If I'm not mistaken, in REPL only the last three results are available (*3 is, but *4 and further are not), at least per http://clojure.org/repl_and_main
Any suggestions?
Did you take a look at the code? The documentation to watch-dir has this: "The watcher returned by this function is a resource which
should be closed with close-watcher."
Looking at the code, it watch-dir uses send-off, which "Dispatch a potentially blocking action to an agent. Returns the agent immediately.". In other words, to address your first question, there is no implicit var created. If you want to get rid of the agent, you should bind the returned agent to some var and call close-watcher on it afterwards.
To address the second question, take a look at the canonical documentation for agents. Specifically, you can call shutdown-agents, which will shut-down the thread pool (potentially killing other agents as well).
I'm placing Clojure into an existing Java project which heavily uses Jersey and Annotations. I'd like to be able to leverage the existing custom annotations, filters, etc of the previous work. So far I've been roughly using the deftype approach with javax.ws.rs annotations found in Chapter 9 of Clojure Programming.
(ns my.namespace.TestResource
(:use [clojure.data.json :only (json-str)])
(:import [javax.ws.rs DefaultValue QueryParam Path Produces GET]
[javax.ws.rs.core Response]))
;;My function that I'd like to call from the resource.
(defn get-response [to]
(.build
(Response/ok
(json-str {:hello to}))))
(definterface Test
(getTest [^String to]))
(deftype ^{Path "/test"} TestResource [] Test
(^{GET true
Produces ["application/json"]}
getTest
[this ^{DefaultValue "" QueryParam "to"} to]
;Drop out of "interop" code as soon as possible
(get-response to)))
As you can see from the comments, I'd like to call functions outside the deftype, but within the same namespace. At least in my mind, this allows me to have the deftype focus on interop and wiring up to Jersey, and the application logic to be separate (and more like the Clojure I want to write).
However when I do this I get the following exception:
java.lang.IllegalStateException: Attempting to call unbound fn: #'my.namespace.TestResource/get-response
Is there something unique about a deftype and namespaces?
... funny my hours on this problem did not yield an answer until after I asked here :)
It looks like namespace loading and deftypes was addressed in this post. As I suspected the deftype does not automatically load the namespace. As found in the post, I was able to fix this by adding a require like this:
(deftype ^{Path "/test"} TestResource [] Test
(^{GET true
Produces ["application/json"]}
getTest
[this ^{DefaultValue "" QueryParam "to"} to]
;Drop out of "interop" code as soon as possible
(require 'my.namespace.TestResource)
(get-response to)))
I'm playing with someone else's code by examining it in the repl.
It keeps calling System/exit, which brings down my repl. This is infuriating.
In all the code I have access to, I've mocked the calls out.
But it's also calling some library code I don't have the source to, both java and clojure, and this occasionally causes exits too.
Is there any way to catch these calls globally, so that an attempt to call them doesn't kill the repl thread? Ideally it would just throw an exception instead.
I think in java I could install a new SecurityManager to get this effect, but I've never done it
there seems to be something in that line here:
http://jroller.com/ethdsy/entry/disabling_system_exit
So I'm thinking something like:
(System/setSecurityManager (SecurityManager.))
only I somehow need to attach
public void checkPermission( Permission permission ) {
if( "exitVM".equals( permission.getName() ) ) {
throw new ExitTrappedException() ;
}
}
My best shot so far is:
(System/setSecurityManager
(proxy [SecurityManager] []
(checkPermission [p]
(when (= "exitVM" (.getName p))
(throw (Exception. "exit"))))))
or maybe
(System/setSecurityManager
(proxy [SecurityManager] []
(checkExit [n] false)))
But they both just destroy the repl
Or is there a better way of doing this?
Use AspectJ and intercept all Calls to System.exit() with a no op.
But you are right, just configuring the security manager would be saner.
You can also use clj-sandbox to restrict code you don't trust.
This one works for me in both, Clojures simple REPL, and in the Lein REPL, too
(def SM (proxy [SecurityManager] []
(checkPermission
[^java.security.Permission p]
(when (.startsWith (.getName p) "exitVM")
(throw (SecurityException. "exit"))))))
(System/setSecurityManager SM)
Ah. Even in the Cider REPL in Emacs.
The name is actually "exitVM.n", where n is the numeric exit code passed to System/exit
I still have an issue to extend this security manager. Surprisingly many Clojure functions call the security manager, and thus, when used inside of it, give an infinite loop, aka StackOverflowException.
(For the latter I opened anothe question: Security Manager in Clojure )
You can try this: http://download.oracle.com/javase/6/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)