首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类/forName在Clojure中不尊重ContextClassLoader?

类/forName在Clojure中不尊重ContextClassLoader?
EN

Stack Overflow用户
提问于 2012-06-07 23:40:18
回答 1查看 1.5K关注 0票数 6

我是一个正在运行的服务的REPLed,并且有一个变量指向一个类加载器,其中装载了一个插件(安装了my.package )。

REPL使用的DynamicClassLoader不包括我希望与之交互的插件;尽管有此限制,我希望能够处理从插件加载的类。

以下工作:

代码语言:javascript
复制
=> (.loadClass plugin-classloader "my.package.MyClass")
my.package.MyClass

...whereas如下所示(显式重写线程上下文类加载器):

代码语言:javascript
复制
=> (do
     (.setContextClassLoader (Thread/currentThread) plugin-classloader)
     (Class/forName "my.package.MyClass"))
ClassNotFoundException my.package.MyClass  java.net.URLClassLoader$1.run (URLClassLoader.java:202)

...and也不这样做(显式地重写线程上下文类加载器和clojure.lang.Compiler/加载器引用):

代码语言:javascript
复制
=> (let [dcl (clojure.lang.DynamicClassLoader. plugin-classloader)]
     (.setContextClassLoader (Thread/currentThread) dcl)
     (with-bindings* {clojure.lang.Compiler/LOADER dcl}
       (eval '(pr-str (Class/forName "my.package.MyClass")))))
ClassNotFoundException my.package.MyClass  java.net.URLClassLoader$1.run (URLClassLoader.java:202)

...and也不是这样的:

代码语言:javascript
复制
=> my.package.MyClass
CompilerException java.lang.ClassNotFoundException: my.package.MyClass, compiling:(NO_SOURCE_PATH:0)

设置时,Class.forName()不应该使用线程上下文类加载器吗?我正在尝试对第三方代码进行一些调用,进行自省;即使应该设置线程上下文类加载器,所讨论的工具在ClassNotFoundExceptions中也会失败。

在我显式设置上下文类加载器的情况下,堆栈跟踪演示了Clojure的DynamicClassLoader (而不是plugin中的BundleClassLoader ):

代码语言:javascript
复制
=> (e)
java.lang.ClassNotFoundException: my.package.MyClass
 at java.net.URLClassLoader$1.run (URLClassLoader.java:202)
    java.security.AccessController.doPrivileged (AccessController.java:-2)
    java.net.URLClassLoader.findClass (URLClassLoader.java:190)
    clojure.lang.DynamicClassLoader.findClass (DynamicClassLoader.java:61)
    java.lang.ClassLoader.loadClass (ClassLoader.java:306)
    java.lang.ClassLoader.loadClass (ClassLoader.java:247)
    java.lang.Class.forName0 (Class.java:-2)
    java.lang.Class.forName (Class.java:169)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-06-08 19:45:50

REPL调用的clojure.lang.Compiler/eval使用的是clojure.lang.Compiler/LOADER,而不是线程本地类加载器.在调用eval之前,一个适当的类加载器需要绑定到这个var --因此,添加一个包装层可以解决这个问题:

代码语言:javascript
复制
=> (let [dcl (clojure.lang.DynamicClassLoader. plugin-classloader)]
     (with-bindings {clojure.lang.Compiler/LOADER dcl}
       (eval '(Class/forName "my.package.MyClass"))))
my.package.MyClass
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10941330

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档