Java-Clojure Interop: Calling Clojure From Java

DZone 's Guide to

Java-Clojure Interop: Calling Clojure From Java

· Java Zone ·
Free Resource
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 [http://clojure.org/java_interop] 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"

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}