Monday, March 30, 2009

Java Clojure Interoperability, Calling Clojure from Java

So far, Java interoperability with Clojure is pretty seamless. Calling Java from Clojure is pretty much built into the language. Calling Clojure from Java is easy as well. I didn't do any research before coming up with this example, I essentially looked at the Clojure Java source code and went from that. Here is an example, invoking Clojure and then passing a Spring Framework Context object to the Clojure code, also calling Clojure methods.

There is the advantage in doing this, you can write concise Clojure code and then invoke that module from Java.


package test.toolkit.clojure;


import org.springframework.context.support.ClassPathXmlApplicationContext;

import clojure.lang.Namespace;
import clojure.lang.RT;
import clojure.lang.Symbol;
import clojure.lang.Var;

public class TestSpringLoadClojure {

///////////////////////////////////////////////////////////////////////////


public static void loadScripts() throws Exception {

final String [] contexts = { "conf/applicationContext-test1b.xml" };
final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(contexts);

final Symbol symbolClojureMain = Symbol.create("clojure.main");
final Namespace namespaceClojureMain = Namespace.findOrCreate(symbolClojureMain);
final Var varRequire = Var.intern(RT.CLOJURE_NS, Symbol.create("require"));

final Namespace simpleUtilsNs = Namespace.findOrCreate(Symbol.create("utils.simple_utils"));
final Var locRequire = Var.intern(RT.CLOJURE_NS, Symbol.create("require"));

varRequire.invoke(symbolClojureMain);

locRequire.invoke(Symbol.create("utils.simple_utils"));
System.out.println("1");
Thread.sleep(2000);
System.out.println("*[2a]*");
locRequire.invoke(Symbol.create("utils.simple_utils"));
System.out.println("*[2b]*");
Thread.sleep(1000);

// Call require on our utility clojure code
// Set the variable spring-context for use in the clojure script
Var.intern(Namespace.findOrCreate(Symbol.create("clojure")), Symbol.create("*spring-context*"), context);
locRequire.invoke(Symbol.create("utils.test_use_utils"));

// This will work, get the length
final Var len = Var.intern(simpleUtilsNs, Symbol.create("length"));
System.out.println(len.invoke("1234"));

}

public static void main(final String [] args) throws Exception {

System.out.println("Running");
loadScripts();
System.out.println("Done");

}

}


Original Source on the Clojure Group Forum

No comments: