2017-05-30 7 views
5

Ich versuche, groovy Skripts in einem isolierten Klassenlader auszuführen, damit sie nicht im Kontext der Abhängigkeiten der aufrufenden Klasse ausgeführt werden.Wie kann ich groovige Skripte in einem isolierten Classloader ausführen?

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

Jede Variation des oben, dass ich versucht habe immer zu

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) 

Ich habe dies zurück auf groovy.util.GroovyScriptEngine#loadScriptByName verfolgt, wo das Skript in eine Class<T> geparst wird, wobei T der Name des Skripts selbst ist.

Meine Theorie ist, dass dies durch binäre Inkompatibilität zwischen der groovigen Laufzeit in der aufrufenden Klasse und der groovigen Laufzeit in einem eigenständigen Klassenlader verursacht wird, weil groovy synthetische Klassen aus Skripten durch Reflexion erzeugt.

Irgendwelche Ideen, wie dies erreicht werden kann?

+1

Ich würde versuchen, die GroovyScriptEngine auch von diesem Classloader instanziieren. Es sieht so aus, dass die generierten Klassen nicht zu 100% isoliert sind –

Antwort

2

versuchen, GroovyScriptEngine nicht direkt, sondern durch rootLoader.loadClass() zu erstellen und engine.run durch Reflexion aufrufen.

Verwandte Themen