Mitch Pronschinske is the Lead Research Analyst at DZone. Researching and compiling content for DZone's research guides is his primary job. He likes to make his own ringtones, watches cartoons/anime, enjoys card and board games, and plays the accordion. Mitch is a DZone Zone Leader and has posted 2576 posts at DZone. You can read more from them at their website. View Full User Profile

Java-Clojure Interop: Calling Clojure From Java

  • submit to reddit
Clojure is quickly becoming one of the more popular JVM languages because of its high performance and excellent handling of concurrency.  Rich Hickey's talk entitled "An Introduction For Java Programmers" is a great resource for Java programmers who are interested in learning Clojure.  For a basic overview of Clojure you can check out this Clojure Scripting tutorial, but one of the most sought after pieces of knowledge is how to interoperate [] between Java and Clojure.  There are several ways to interoperate including embedding Clojure in Java and calling Clojure from Java.  This short tutorial explains a method for calling Clojure from Java.

Some sites will recommend using clojure.lang.RT.  For this method, we assume that you've already built a .jar from your Clojure project and added it to the class path.  Calling Clojure from Java isn't accomplished simply by compiling to a .jar and calling the internal methods.  This example uses a simple Clojure file that can be compiled to a .jar (the example uses Clojure-1.1.0 .jar):
(ns com.domain.tiny
:name com.domain.tiny
:methods [#^{:static true} [binomial [int int] double]]))

(defn binomial
"Calculate the binomial coefficient."
[n k]
(let [a (inc n)]
(loop [b 1
c 1]
(if (> b k)
(recur (inc b) (* (/ (- a b) b) c))))))

(defn -binomial
"A Java-callable wrapper around the 'binomial' function."
[n k]
(binomial n k))

(defn -main []
(println (str "(binomial 5 3): " (binomial 5 3)))
(println (str "(binomial 10042 111): " (binomial 10042 111)))
When you run the .jar you get a result similar to this one:
(binomial 5 3): 10
(binomial 10042 111): 49068389575068144946633777...

This is a Java program that invokes the -binomial function in the tiny.jar:
import com.domain.tiny;

public class Main {

public static void main(String[] args) {
System.out.println("(binomial 5 3): " + tiny.binomial(5, 3));
System.out.println("(binomial 10042, 111): " + tiny.binomial(10042, 111));
And this is the result:
(binomial 5 3): 10.0
(binomial 10042, 111): 4.9068389575068143E263

Take note of the :methods keyword in the gen-class statement. This lets you access the Clojure function in a way similar to Java's static methods.  Then you just create a wrapper function that Java can call.  You can also see that the second version of -binomial has a dash in front of it.  

Because it is implemented as a Java class library, Clojure can also be easily embedded your Java applications, load code, and call functions.  Bob Martin of Object Mentor has another example of calling into Clojure from Java on his blog post: "Java Calling Clojure"


Byju Veedu replied on Fri, 2010/03/26 - 4:29am

The first link given is pointing to the same article

Jacek Furmankiewicz replied on Fri, 2010/03/26 - 8:38pm

I love these type of blanket statements

Clojure is quickly becoming one of the more popular JVM languages because of its high performance and excellent handling of concurrency

A quick job search on Dice and Monster reveals pretty much 0 Clojure jobs (it's mentioned as a "nice to know" in two of them. That hardly qualifies as "quickly becoming one of the more popular JVM languages".

Frankly, I am interested to see how many of these functional-oriented languages survive once lambdas come in Java 7. They may not be as functional as these, but I think many Java developers who have some interest in functional programming will find them "functional enough".




Nabeel Manara replied on Fri, 2012/01/27 - 8:58am

I got curious and followed the same procedure. I got errors initially. But the errors were not that informative.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.