2012-03-21 48 views
1

在试图从非默认的类路径装载AOT编译的类加载 ,我收到以下异常: clojure:名称空间中的ExceptionInInitializerError。从非默认的classpath

Traceback (innermost last): 
    File "test.jy", line 10, in ? 
     at clojure.lang.Namespace.<init>(Namespace.java:34) 
     at clojure.lang.Namespace.findOrCreate(Namespace.java:176) 
     at clojure.lang.Var.internPrivate(Var.java:149) 
     at aot_demo.JavaClass.<clinit>(Unknown Source) 
     at java.lang.Class.forName0(Native Method) 
     at java.lang.Class.forName(Class.java:247) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
     at java.lang.reflect.Method.invoke(Method.java:597) 
java.lang.ExceptionInInitializerError: java.lang.ExceptionInInitializerError 

我可以用下面的琐碎重现此project.clj

(defproject aot-demo "0.1.0-SNAPSHOT" 
    :dependencies [[org.clojure/clojure "1.3.0"]] 
    :aot [aot-demo.core]) 

...和src/aot_demo/core.clj定义如下:

(ns aot-demo.core 
    (:gen-class 
    :name aot_demo.JavaClass 
    :methods [#^{:static true} [lower [java.lang.String] java.lang.String]])) 

(defn -lower [str] (.toLowerCase str)) 

以下Jython脚本就足以触发漏洞:如果测试脚本开始与uberjar已经在CLASSPATH可变

#!/usr/bin/jython 
import java.lang.Class 
import java.net.URLClassLoader 
import java.net.URL 
import os 

customLoader = java.net.URLClassLoader(
    [java.net.URL('file://%s/target/aot-demo-0.1.0-SNAPSHOT-standalone.jar' 
        % (os.getcwd()))]) 

java.lang.Class.forName('aot_demo.JavaClass', True, customLoader) 

然而,例外情况发生。

这是怎么回事?我正在尝试为Clojure中的BaseX数据库编写一个插件;上面的内容准确地表示了他们的插件加载机制如何工作,以便为此问题提供SSCE。

+0

看起来像是CLJ-260,“Resolution:Declined”。 http://dev.clojure.org/jira/browse/CLJ-260 – 2012-03-21 23:18:44

回答

0

BaseX使用的插件加载机制应该扩展以修改当前线程的上下文类加载器。对于给定的示例代码(在Jython中),这看起来如下所示:

currentThread = java.lang.Thread.currentThread() 
oldLoader = currentThread.getContextClassLoader() 

currentThread.setContextClassLoader(customLoader) 
try: 
    cls = java.lang.Class.forName('aot_demo.JavaClass', True, customLoader) 
finally: 
    currentThread.setContextClassLoader(oldLoader) 
相关问题