2017-05-30 75 views
5

我想在独立的类加载器中运行groovy脚本,以便它们不会在调用类的依赖关系的上下文中执行。如何在独立的类加载器中执行groovy脚本?

Path log4j = Paths.get("..../lib/log4j-1.2.17.jar"); 
    Path groovy = Paths.get("..../lib/groovy-all-2.1.3.jar"); 
    RootLoader rootLoader = new RootLoader(new URL[] { log4j.toUri().toURL(), groovy.toUri().toURL() }, null); 
    GroovyScriptEngine engine = new GroovyScriptEngine(".../src/main/resources", rootLoader); 
    engine.run("Standalone.groovy", ""); 
Standalone.groovy
import org.apache.log4j.BasicConfigurator 
import org.apache.log4j.Logger 

Logger logger = Logger.getLogger(getClass()) 
BasicConfigurator.configure() 
logger.info("hello world") 
pom.xml摘录
<dependency> 
     <groupId>org.codehaus.groovy</groupId> 
     <artifactId>groovy-all</artifactId> 
     <version>2.1.3</version> 
    </dependency> 

,我已经一直试图就上述任何变化导致

Exception in thread "main" groovy.lang.GroovyRuntimeException: Failed to create Script instance for class: class Standalone. Reason: java.lang.ClassCastException: Standalone cannot be cast to groovy.lang.GroovyObject 
    at org.codehaus.groovy.runtime.InvokerHelper.createScript(InvokerHelper.java:443) 
    at groovy.util.GroovyScriptEngine.createScript(GroovyScriptEngine.java:564) 
    at groovy.util.GroovyScriptEngine.run(GroovyScriptEngine.java:551) 
    at groovy.util.GroovyScriptEngine.run(GroovyScriptEngine.java:537) 

我已经将其跟踪到groovy.util.GroovyScriptEngine#loadScriptByName,其中脚本被解析为Class<T>,其中T是脚本本身的名称。

我的理论是,这是由于groovy通过反射创建合成类从脚本创建出来的,因此调用类中运行的groovy运行时与运行在独立类加载器中的groovy运行时之间的二进制不兼容导致。

有关如何完成这一任何想法?

+1

我会尝试从该类加载器实例化GroovyScriptEngine。它看起来生成的类不是100%孤立的 –

回答

2

尝试创建GroovyScriptEngine不是直接,而是通过rootLoader.loadClass()并通过反射调用engine.run