It's easy to use the REPL and determine if you have things correct.
user=> Thread$UncaughtExceptionHandlerThis works without issue, because java.lang is (generally) available in Clojure.
java.lang.Thread$UncaughtExceptionHandler
If you want access to an inner class that is not in java.lang you'll want to import it directly. For example, the following REPL session shows how you can access the ThreadPoolExecutor.DiscardPolicy class.
user=> ThreadPoolExecutor$DiscardPolicyReturning the entire class in the REPL should suffice as proof that everything is working fine; however, the code below is a brief example of using Thread$UncaughtExceptionHandler in a larger context.
java.lang.Exception: Unable to resolve symbol: ThreadPoolExecutor$DiscardPolicy in this context (NO_SOURCE_FILE:0)
user=> (ns my-ns (:import [java.util.concurrent ThreadPoolExecutor$DiscardPolicy]))
java.util.concurrent.ThreadPoolExecutor$DiscardPolicy
my-ns=> ThreadPoolExecutor$DiscardPolicy
java.util.concurrent.ThreadPoolExecutor$DiscardPolicy
jfields:Documents jfields$ cat inner.cljAs you can see from the command-line output, the exception is handled by the proxy of Thread$UncaughtExceptionHandler.
(def handler (proxy [Thread$UncaughtExceptionHandler] []
(uncaughtException [thread exception]
(println thread exception))))
(Thread/setDefaultUncaughtExceptionHandler handler)
(/ 12 0)
jfields:Documents jfields$ java -cp ../dev/clojure-current/clojure.jar clojure.main -i inner.clj
#<Thread Thread[main,5,main]> #<CompilerException java.lang.ArithmeticException: Divide by zero (inner.clj:0)>
Outer$Inner is actual name of inner classes in bytecode . (the fact that they are "inner" is just syntactic and compiler sugar at the java language level)
ReplyDeleteThanks for posting Jay, I had a hard time figuring this out (clojure docs are a little sprase on this imho), your post saved me ;)
ReplyDelete