Hi!

I ran into the same issue while helping a colleague in working on the 
[sonar-clojure Sonarqube|https://github.com/hjhamala/sonar-clojure/] 
plugin. A quick search on Clojure JIRA reveals couple of discussions, [this 
one|https://dev.clojure.org/jira/browse/CLJ-260?focusedCommentId=23453&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-23453]
 
maybe the most relevant.

In our case, we also wrote a piece of Java code to set up the threads 
context classloader so that RT can load itself.

        ClassLoader ccl = Thread.currentThread().getContextClassLoader();
       try {
           Thread.currentThread().setContextClassLoader(this.getClass().
getClassLoader());
           RT.init();
           Var.pushThreadBindings(RT.map(RT.USE_CONTEXT_CLASSLOADER, RT.F));
       } finally {
           Thread.currentThread().setContextClassLoader(ccl);
       }



I think it might be neat to have a way to allow the RT to load itself from 
the classloader that loaded the RT class itself, instead of the thread's 
context classloader. A system property might be enough, but I started to 
think about a way to specify this even in a gen-classed. This would need 
less "glue", since a gen-classed class causes the RT class to load, in 
which case there is a need for callsite glue to setup the thread's context 
classloader.

Maybe a new JIRA ticket might be a good place for the discussion :)

- Kimmo

torstai 7. helmikuuta 2019 23.02.24 UTC+2 henrik42 kirjoitti:
>
> Rastko - thanks for the reply. My 
> <wildfly-root>/modules/buttle/main/module.xml looks like this:
>
>     <?xml version="1.0" encoding="UTF-8"?>
>     <module xmlns="urn:jboss:module:1.1" name="buttle">
>       <resources>
>         <resource-root path="buttle-standalone.jar"/>
>       </resources>
>       <dependencies>
>         <module name="postgres"/>
>         <module name="javax.api"/> 
>       </dependencies>
>     </module> 
>
> And the driver in standalone.xml:
>
>     <drivers>
>       <driver name="buttle-driver" module="buttle"/>
>     </drivers>
>
> The loading of my classes incl. clojure.lang.RT works "in
> principle". Only when Clojure uses the TCCL to load clojure/core.clj 
> things fail. To see what's
> happening I changed
> java/buttle/SetContextClassLoaderInStaticInitializer.java to:
>
>     package buttle;
>     public class SetContextClassLoaderInStaticInitializer {
>         static {
>             ClassLoader tccl = 
> Thread.currentThread().getContextClassLoader();
>             System.out.println("tccl = " + tccl);
>             System.out.println("tccl sees clojure/core.clj at " + 
> tccl.getResource("clojure/core.clj"));
>             ClassLoader myCl = 
> SetContextClassLoaderInStaticInitializer.class.getClassLoader();
>             System.out.println("myCl = " + myCl);
>             System.out.println("myCl sees clojure/core.clj at " + 
> myCl.getResource("clojure/core.clj"));
>             
> Thread.currentThread().setContextClassLoader(SetContextClassLoaderInStaticInitializer.class.getClassLoader());
>         }
>     }
>
> I get:
>
>     tccl = ModuleClassLoader for Module "org.jboss.as.controller" version 
> 4.0.0.Final from local module loader @6adca536
>        (finder: local module finder @357246de (roots: 
> C:\henrik\wildfly-12.0.0.Final\modules,C:\henrik\wildfly-12.0.0.Final\modules\system\layers\base))
>     tccl sees clojure/core.clj at null
>     myCl = ModuleClassLoader for Module "buttle" from local module loader 
> @6adca536 (finder: local module finder @357246de
>        (roots: 
> C:\henrik\wildfly-12.0.0.Final\modules,C:\henrik\wildfly-12.0.0.Final\modules\system\layers\base))
>     myCl sees clojure/core.clj at 
> jar:file:/C:/henrik/wildfly-12.0.0.Final/modules/buttle/main/./buttle-standalone.jar!/clojure/core.clj
>
> I checked that my class and clojure.lang.RT are loaded with the same 
> classloader. So the TCCL which Wildfly puts into
> place cannot load clojure/core.clj. But the (module) classloader which 
> loaded my class and clojure.lang.RT CAN load it. That's
> why I came up with the idea of replacing the TCCL before 
> clojure.lang.RT<cinit> runs.
>
> I believe that the way Wildfly uses the different classloaders is 
> absolutly on purpose. In [1] you find
> arguments for why libraries should not use the TCCL for certain things. 
> And one could argue, that Clojure
> is doing it the wrong way.
>
> I believe that the existence of clojure.core/*use-context-classloader* is 
> due to someone realizing that there are
> cases when you cannot use the TCCL (like in mine). In my case though I 
> just can't set that var because of the chicken-egg-problem
> as I pointed out.
>
> I think that adding additional dependencies or adding exports won't
> change the Module-"org.jboss.as.controller"-classloader. But I'll check 
> tomorrow.
>
> One solution that comes to mind is to change clojure.lang/RT so that the 
> *use-context-classloader* var is not initialized to
> true but to (Boolean/parseBoolean (System/getProperty 
> "clojure.use-context-classloader" "true"))
>
> Henrik
>
> [1] https://developer.jboss.org/wiki/ModuleCompatibleClassloadingGuide
>
>

-- 
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/d/optout.

Reply via email to