Jay Fields is a software developer at DRW Trading. He has a passion for discovering and maturing innovative solutions. His most recent work has been in the Domain Specific Language space where he's delivered applications that empowered subject matter experts to write the business rules of the applications. He is also very interested in maturing software design through software testing. Jay is a DZone MVB and is not an employee of DZone and has posted 116 posts at DZone. You can read more from them at their website. View Full User Profile

Clojure: Using Java Inner Classes

01.13.2011
| 5131 views |
  • submit to reddit

Recently, I wanted to add some specific behavior to my Clojure application when any uncaught exception occurred. This is easy enough by calling the setDefaultUncaughtExceptionHandler (sDUEH); however, it's worth noting that the sDUEH takes a Thread.UncaughtExceptionHandler argument. Clojure has no problem giving you access to inner classes, but the syntax is slightly different: Outer$Inner in Clojure is the same as Outer.Inner in Java.

It's easy to use the REPL and determine if you have things correct.

user=> Thread$UncaughtExceptionHandler
java.lang.Thread$UncaughtExceptionHandler
This works without issue, because java.lang is (generally) available in Clojure.

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$DiscardPolicy
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
Returning 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.
jfields:Documents jfields$ cat inner.clj
(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)>
As you can see from the command-line output, the exception is handled by the proxy of Thread$UncaughtExceptionHandler.

 

From http://blog.jayfields.com/2011/01/clojure-using-java-inner-classes.html

Published at DZone with permission of Jay Fields, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)