This is indeed due to an interesting peculiarity of Clojure's runtime 
implementation. For whatever reason, RT class will fail to initialize if it 
was loaded by a classloader different from the context class loader of the 
executing thread. It may sound somewhat strange in terms of how this can 
actually happen in practice? But it is quite possible if the actual context 
classloader chooses "*parent first*" style of loading classes - thus 
delegating to its parent classloaders (or just the system classloader) 
first. 

This has been discussed on the following thread in this group in some 
detail: 
https://groups.google.com/forum/?hl=en&fromgroups=#!topic/scala-user/Bh_YmI6e-wY

Spring Hadoop chooses an interesting style of classloading delegation when 
it submits the Hadoop "uberjar" using its 
*ParentLastURLClassLoader*implementation. It actually delegates to the system 
classloader first, then 
tries to load classes from the uberjar, and only then goes to the parent 
classloader if it is available. So, if you're running a simple Java process 
(i.e. not inside an application server or web container), as can be the case
in many situations including launching a simple unit test from inside an 
IDE, this *ParentLastURLClassLoader *effectively becomes a "parent first" 
classloader. 

Thus it creates an interesting situation: if *clojure.jar* is present on 
the classpath outside of the "uberjar" (not an unreasonable expectation), 
the RT class will be loaded by the system classloader when the context 
classloader is set to *ParentLastURLClassLoader* classloader. I have 
created an RFE in Spring Hadoop Jira to allow making classloading 
delegation configurable (i.e. allowing true "parent last" delegation as an 
option): SHDP-135 <https://jira.springsource.org/browse/SHDP-135>.

The way to work around these issues is to either ensure that no *clojure.jar
* is present on the main classpath when submitting "uberjars" to Hadoop 
from inside a running live JVM process or replacing a context classloader 
with a custom "true parent last" classloader (assuming the 
SHDP-135<https://jira.springsource.org/browse/SHDP-135>is not addressed) in a 
try/finally block. 

At this point it is *unclear* why Clojure RT class behaves the way it does. 
It is certainly somewhat "unconventional". It would be hugely beneficial 
and *very interesting* to know why the actual implementation of the context 
classloader should matter to the startup of Clojure runtime. I think the 
whole community would benefit greatly from this understanding. 

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to