简体   繁体   中英

How can I execute groovy scripts in an isolated classloader?

I'm trying to run groovy scripts in an isolated classloader so that they are not executed in the context of the calling class' dependencies.

    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 excerpt :
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)

Any variation on the above that I've tried always results in

 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) 

I've tracked this back to groovy.util.GroovyScriptEngine#loadScriptByName where the script is parsed into a Class<T> , where T is the name of the script itself.

My theory is that this is caused by binary incompatibility between the groovy runtime running in the calling class and the groovy runtime running in a standalone class loader, due to the way groovy creates synthetic classes out of scripts through reflection.

Any ideas about how this can be accomplished?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM