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.