我被複制到一個正在運行的服務中,並且有一個var指向一個加載插件的類加載器(安裝了my.package
)。Clojure中的class/forName不尊重ContextClassLoader?
REPL使用的DynamicClassLoader不包含我希望與之交互的插件;我希望能夠使用插件加載的類,儘管有這種限制。
以下工作:
=> (.loadClass plugin-classloader "my.package.MyClass")
my.package.MyClass
...而以下不(明確重寫線程上下文的classloader):
=> (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()
使用線程上下文的classloader設置是什麼時候?我正在嘗試將一些調用轉化爲執行內省魔法的第三方代碼;即使在設置線程上下文類加載器時,所討論的工具也會因爲ClassNotFoundException而失敗。
的情況下,我明確設置的上下文ClassLoader,堆棧跟蹤表明,Clojure的DynamicClassLoader中(而不是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)
好像'eval'是玩一些把戲那裏......你可以嘗試同樣的事情在編譯clojure代碼? – Ankur
@Ankur - 你的意思是AOT編譯的?我的理解是,Clojure的實現是這樣的,它是*所有*編譯代碼,甚至在REPL中輸入。 –
@Ankur事實證明,你是對的 - 它是編譯好的代碼,但當'clojure.lang.Compiler/eval'被調用時,綁定到'clojure.lang.Compiler/LOADER'的'DynamicClassLoader'實例。 –