Calling Clojure from Java and classloader

328 views
Skip to first unread message

Warren Lynn

unread,
Jun 13, 2012, 11:48:28 PM6/13/12
to Clojure
Ok, I hit a wall and really did not see this coming.

Based on what I have read, its really easy for Clojure and Java to
work together. So I wrote some test Clojure code with a very simple
defrecord (say named as "testrec") and AOT compile it, create a jar
file, and add it to a "HelloWorld" java project in Eclipse. I can
create object of class "testrec" and run its member functions. Cool,
no problem.

But then I put the same thing into my target Java system (for which I
am consider Clojure for production use), I got
"java.lang.ExceptionInInitializerError" exception when trying to
create my "testrec" object. A little bit more digging suggests this is
related to class loader, which I don't know much about. According to a
web page, I need to do this:

Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());

before calling the constructor of my "testrec" class. Tried that, but
I got

java.security.AccessControlException: access denied
("java.lang.RuntimePermission" "setContextClassLoader")

Seems I cannot change the context class loader.

What is the solution here?

Sorry for the long post. But I hope this is not a dead end. Thanks a
lot.

Aaron Cohen

unread,
Jun 15, 2012, 10:31:36 AM6/15/12
to clo...@googlegroups.com
It's not really a good idea to AOT your code and then directly try to
use it from java. The generated java bytecode isn't guaranteed to be
stable across versions of clojure, and you're depending on
implementation details.

One way to use your clojure code from java is through RT. An example
would be the accepted answer here:
http://stackoverflow.com/questions/2181774/calling-clojure-from-java

Another tack you can take is to use gen-class to create a "real" java
class from clojure and use that as an entry point to your clojure
code.

--Aaron

Warren Lynn

unread,
Jun 15, 2012, 5:35:31 PM6/15/12
to clo...@googlegroups.com

It's not really a good idea to AOT your code and then directly try to
use it from java. The generated java bytecode isn't guaranteed to be
stable across versions of clojure, and you're depending on
implementation details.
 
One way to use your clojure code from java is through RT. An example
would be the accepted answer here:
http://stackoverflow.com/questions/2181774/calling-clojure-from-java


I really don't like the RT way (very clumsy), so I want to avoid it if possible. My .jar file will include Clojure itself in it, so compatibility with different version of Clojure is not a problem for me.
But is there any other pitfalls using AOT?

Another tack you can take is to use gen-class to create a "real" java
class from clojure and use that as an entry point to your clojure
code.


 My understanding is "defrecord" actually generate a real named java class. And I can use it in Eclipse project so it seems that is the case.

BTW: my issue is solved by using some kind of annotation defined by the target Java framework. However, I could have been in a dead end if there is no such annotation and the classloader is messed up. So just as someone says "things are never as simple as it seems".



Reply all
Reply to author
Forward
0 new messages