2012-06-07 22 views
5

Çalışan bir servise REPL girdim ve eklentinin yüklü olduğu bir sınıf yükleyiciyi işaret eden bir var (my.package yüklü).Clojure Sınıf/forName ContextClassLoader'a uymuyor mu?

REPL tarafından kullanılan DynamicClassLoader, etkileşimde bulunmak istediğim eklentiyi içermez; Bu sınırlamaya rağmen eklentiden yüklenen sınıflarla çalışmayı diliyorum.

aşağıdaki çalışır:

(açıkça iplik bağlam classloader geçersiz kılma) gelmez aşağıdaki oysa
=> (.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) 

... ve ne yapar bu (açıkça geçersiz kılma iş parçacığı bağlamı sınıflayıcısı ve clojure.lang.Compiler/LOADER referansı):

=> (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) 

... ve ne bu kapsamaz: ayarlandığında

=> my.package.MyClass 
CompilerException java.lang.ClassNotFoundException: my.package.MyClass, compiling:(NO_SOURCE_PATH:0) 

Class.forName() iplik bağlam classloader kullanmak gerekmez mi? Introspection magic yapan üçüncü taraf koduna bazı aramalar yapmaya çalışıyorum; Söz konusu araçlar, thread context sınıf yükleyicisi ayarlanmalıdır bile ClassNotFoundExceptions ile başarısız oluyor.

=> (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) 
+0

eval' bazı hile oynuyor 'gibi görünüyor: yani bu soruna sarma eserlerin bir katman ekleyerek - Uygun bir classloader denir eval önce bu var'a bağlı gerekiyor derlenmiş clojure kodunda? – Ankur

+0

@Ankur - AOT derlenmiş mi demek istiyorsun? Benim anlayışım, Clojure’ın uygulanmasının, REPL’de girilmiş olsa dahi, * derlenmiş bir kod olması. –

+0

@Ankur Anlaşıldığı üzere, haklıydınız - bu _is_ kodunu derlediniz, fakat "DynamicClassLoader" örneği "clojure.lang.Compiler/eval" çağrıldığında "clojure.lang.Compiler/LOADER" öğesine bağlandı. . –

cevap

5

: Ben açıkça bağlam classloader ayarlıyorum durumda


, yığın izleme Clojure en DynamicClassLoader (ziyade eklenti-classloader var içinde BundleClassLoader) kullanımda olduğunu gösteriyor REPL tarafından çağrıldığı gibi clojure.lang.Compiler/eval, thread-yerel sınıf yükleyicisi değil, clojure.lang.Compiler/LOADER kullanır. Eğer aynı şeyi deneyebilirsiniz ...

=> (let [dcl (clojure.lang.DynamicClassLoader. plugin-classloader)] 
    (with-bindings {clojure.lang.Compiler/LOADER dcl} 
     (eval '(Class/forName "my.package.MyClass")))) 
my.package.MyClass