Как выполнить скрипты 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 Runtime, выполняемой в вызывающем классе, и Groovy Runtime, выполняемой в автономном загрузчике классов, из-за того, что Groovy создает синтетические классы из сценариев посредством отражения.
Любые идеи о том, как это может быть достигнуто?
1 ответ
Попытаться создать GroovyScriptEngine
не напрямую, а через rootLoader.loadClass()
и позвонить engine.run
через отражение.