Affects Version/s: Release 1.4, Release 1.5
Fix Version/s: None
Environment:Tested on Mac OS X 10.8 and Oracle JVM 1.7.0 update 13.
When a client program uses a remote service which uses RMI, and the service returns a object which created with gen-class with clojure as the return value, the return value is not loadable at client side.
At client side, a following exeption will be thrown.
If you want to see this issue at your computer, clone my example project from my github.
git clone git://github.com/tyano/clojure_genclass_fix.git
and build them (You must have installed Leiningen 2):
You will see a message "Server ready. " or "Server ready. (rebind)".
At last, start client program:
Without my patch, you will see a same Exception described above. But with clojure with my patch, you will see a right response message: "response = this is sample."
The reason of this problem is in bytecodes generated by gen-class. A gen-classed class (in this case, SampleInterfaceImpl.class) uses a static-initializer for loading SampleInterfaceImpl__init.class (which load other classes which implements functions in the class). The static-initializer is like bellow: (the following code is decompiled with JD - http://java.decompiler.free.fr/?q=jdgui )
Very simple code. it seems non-problematic. But RT.load changes the classloader for loading __init.class in the processing! RT.load in default uses a context-classloader for loading classes. But all classes depending on a gen-classed class must be loaded a same classloader with a main gen-classed class. In this case, RT.load must use a remote URLClassLoader which load a main class.
So, gen-class must be create bytecodes that is same with the following java code.
With this code, RT.load will uses a same classloader which load SampleInterfaceImpl.class.
My patch for gen-class will create bytecodes equal to the above example.
You can use an attached patch '20130204_fix_classloader.diff', or pull 'fix_classloader' branch from my github repositry ( email@example.com:tyano/clojure.git ).