私は実行中のサービスにREPLされ、プラグインがロードされたクラスローダーを指し示すvarを持っています(my.package
がインストールされています)。ClojureのClass/forNameはContextClassLoaderを尊重していませんか?
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)
...そしてどちらも、これは(明示的にオーバーライドしスレッドコンテキストクラスローダーとクローラーのコンパイラ/ロードのリファレンス):
=> (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()
はスレッドコンテキストクラスローダを使用するべきではないでしょうか。私はイントロスペクション・マジックを行っている第三者コードにいくつかの呼び出しをしようとしています。スレッドコンテキストクラスローダーを設定する必要がある場合でも、問題のツールはClassNotFoundExceptionsで失敗します。
=> (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'はそこにいくつかのトリックを再生している 'のように思える...あなたが同じことを試すことができますコンパイルされたクロージャーコードで? – Ankur
@Ankur - あなたはAOTコンパイルを意味しますか?私の理解は、Clojureの実装はREPLで入力された*すべての*コンパイルされたコードであるということです。 –
@Ankur 'clojure.lang.Compiler/eval'が問題と呼ばれるとき、' DynamicClassLoader'インスタンスは 'clojure.lang.Compiler/LOADER'にバインドされていました。 。 –