2017-05-30 59 views
5

Próbuję uruchomić groovy skrypty w izolowanym programie ładującym klasy, tak aby nie były wykonywane w kontekście zależności klasy wywołującej.Jak mogę wykonywać groovy skrypty w izolowanym programie ładującym klasy?

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 fragment:
<dependency> 
     <groupId>org.codehaus.groovy</groupId> 
     <artifactId>groovy-all</artifactId> 
     <version>2.1.3</version> 
    </dependency> 

Każda wariacja na powyższym Próbowałem zawsze skutkuje

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) 

Śledziłem to z powrotem do groovy.util.GroovyScriptEngine#loadScriptByName, gdzie skrypt jest przetwarzany na Class<T>, gdzie T jest nazwą samego skryptu.

Moja teoria jest taka, że ​​jest to spowodowane binarną niezgodnością pomiędzy fajnym środowiskiem wykonawczym uruchomionym w klasie wywołującej a groovem środowiskiem uruchomieniowym działającym w autonomicznym programie ładującym klasy, ze względu na sposób, w jaki groovy tworzy syntetyczne klasy ze skryptów poprzez odbicie.

Jakieś pomysły na temat tego, jak można to osiągnąć?

+1

Chciałbym również spróbować utworzyć instancję GroovyScriptEngine z tego programu ładującego klasy. Wygląda na to, że generowane klasy nie są w 100% izolowane –

Odpowiedz

2

spróbuj utworzyć GroovyScriptEngine bezpośrednio, ale przez rootLoader.loadClass() i zadzwoń pod numer engine.run poprzez odbicie.