Tech behind Tech

Raw information. No finesse :)

Calling java from Clojure

leave a comment »


Importing Java Class

In repl, when you want to import one Java class you can do

(import 'java.util.Date)

When you want to import more Java classes from a same package you can do

(import [java.util Date HashMap])
        (:import [java.util Date HashMap]))

Creating Instances

(import 'java.util.Date)

(def today (new Date))

;; or

(def today (Date.))

Calling Java instance methods

user> (import 'java.util.Date)
user> (let [today (Date.)]
        (.getTime today))

Calling Java static methods

user> (System/currentTimeMillis)

Sugar sytax:


You want to write a function that will return UTC Java Calendar object set at a specific time.

user> (import [java.util Calendar TimeZone Date])
user> (defn utc-time [d]
        (let [cal (Calendar/getInstance)]
              (.setTimeZone cal (TimeZone/getTimeZone "UTC"))
              (.setTime cal d)


The let block is ugly. We could use doto to make this code better.

user> (import [java.util Calendar TimeZone Date])	
user> (defn utc-time [d]        
         (doto (Calendar/getInstance)
              (.setTimeZone (TimeZone/getTimeZone "UTC"))
              (.setTime d)))


Dot Dot:

Sometimes in java you want to make calls in chain

Bad way

user> (.length (.getProperty (System/getProperties) ""))

Better way

user> (. (. (System/getProperties) getProperty "") length)

Even Better

user> (..
       (getProperty "")

Avoiding Reflection

By default jvm will be using reflection to identify type. Reflection is slow. But we can give type hints that way jvm does not have to use reflection. For example we can rewrite utc-time with type-hints like this

user> (set! *warn-on-reflection* true)
user> (defn str-length [s] (.length s))
Reflection warning, NO_SOURCE_FILE:1 - reference to field length can't be resolved.
user> (defn str-length [#^String s] (.length s))

Implementing interfaces and extending classes

Let us implement Java Runnable interface

user> (proxy [Runnable] []
        (run []
             (println "running ...")))
#<Object$Runnable$36fc6471 user.proxy$java.lang.Object$Runnable$36fc6471@6dd33544>

In clojure 1.2, you could use reify macro to implement. In fact it is better than using proxy.

user> (reify Runnable
             (run [this]
                  (println "running ...")))
#<user$eval1664$reify__1665 user$eval1664$reify__1665@574f7121>

Written by Siva Jagadeesan

October 11, 2010 at 10:43 pm

Posted in Clojure

Tagged with , ,

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Get every new post delivered to your Inbox.

Join 147 other followers

%d bloggers like this: