我被 REPLed 到一个正在运行的服务中,并且有一个指向一个类加载器的 var 加载了一个插件(my.package
安装了)。
REPL 使用的 DynamicClassLoader 不包括我希望与之交互的插件;尽管有这个限制,我希望能够使用从插件加载的类。
以下作品:
=> (.loadClass plugin-classloader "my.package.MyClass")
my.package.MyClass
...而以下没有(明确覆盖线程上下文类加载器):
=> (do
(.setContextClassLoader (Thread/currentThread) plugin-classloader)
(Class/forName "my.package.MyClass"))
ClassNotFoundException my.package.MyClass java.net.URLClassLoader$1.run (URLClassLoader.java:202)
...这也不是(显式覆盖线程上下文类加载器和clojure.lang.Compiler/LOADER 参考):
=> (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)
...这也不是:
=> my.package.MyClass
CompilerException java.lang.ClassNotFoundException: my.package.MyClass, compiling:(NO_SOURCE_PATH:0)
设置时不应该Class.forName()
使用线程上下文类加载器吗?我正在尝试调用 3rd-party 代码来做自省魔法;即使应该设置线程上下文类加载器,有问题的工具也会因 ClassNotFoundExceptions 而失败。
在我明确设置上下文类加载器的情况下,堆栈跟踪表明正在使用 Clojure 的 DynamicClassLoader(而不是 plugin-classloader var 中的 BundleClassLoader):
=> (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)