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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.