Reputation: 860
I'm having problems to port a Java standalone program using the GroovyScriptEngine inside Jboss.
My program launches groovy scripts, and it needs to load dynamically classes to launch them. It does something like the following:
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
final String myJarPath = "/tmp/myJar.jar";
URLClassLoader loader = null;
try {
final URL url = new File(myJarPath).toURI().toURL();
loader = new URLClassLoader(new URL[] { url},oldLoader);
} catch (MalformedURLException e) {
e.printStackTrace();
}
Thread.currentThread().setContextClassLoader(loader);
ScriptEngineManager seManager = new ScriptEngineManager(loader);
final Map<String, Object> bindingAttributes = new HashMap<>() ;
final ScriptEngine scriptEngine = seManager.getEngineByName("groovy");
final SimpleBindings simpleBindings = new SimpleBindings(bindingAttributes);
scriptEngine.setBindings(simpleBindings, ScriptContext.GLOBAL_SCOPE);
FileReader fileReader = null;
BufferedReader bufferedReader = null;
fileReader = new FileReader(new File("/my/path/to/groovyFile/file.groovy"));
bufferedReader = new BufferedReader(fileReader);
final Object eval = scriptEngine.eval(bufferedReader);
System.out.println(eval);
in myJar.jar there are classes needed by the groovy script, not by the java program that launches the groovy scrits itself. In this way it works nicely: I just need to include the following maven dependency.
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.3.6</version>
</dependency>
If I port my code in a resource adapter (a JCA connector), though I've added all the required dependencies, when I do:
final ScriptEngine scriptEngine = seManager.getEngineByName("groovy");
I get a NullPointerException.
If I try to feed the ScriptEngineManager registerig groovy manually, such as:
...
Thread.currentThread().setContextClassLoader(loader);
ScriptEngineManager seManager = new ScriptEngineManager(loader);
final Map<String, Object> bindingAttributes = new HashMap<>() ;
############################################
## register it manually ##
############################################
final GroovyScriptEngineFactory factory = new GroovyScriptEngineFactory();
seManager.registerEngineName("groovy", factory);
final ScriptEngine scriptEngine = seManager.getEngineByName("groovy");
final SimpleBindings simpleBindings = new SimpleBindings(bindingAttributes);
scriptEngine.setBindings(simpleBindings, ScriptContext.GLOBAL_SCOPE);
final GroovyScriptEngineFactory factory = new GroovyScriptEngineFactory();
seManager.registerEngineName("groovy", factory);
final ScriptEngine scriptEngine = seManager.getEngineByName("groovy");
The script gets loaded but the classpath does not contain the extra classes provided in the myJar.jar. So I get a ClassNotFoundException. If this class is included in the resource adapter archive it works fine, so it seems the script is only able to see the classes contained in the resource adapter.
Do you have any idea on how can I solve this issue, apart including all the extra classes on the resource adapter (current woraround). Thank you very much.
Upvotes: 2
Views: 736
Reputation: 5883
I haven't encountered this specific issue before, but I have had problems getting a JBoss-deployed war file to obtain a Groovy Script Engine. What I did to resolve my problem was to create a global Groovy module:
1) Create directory $JBOSS_HOME/modules/org/codehaus/groovy/main/
2) Copy groovy-all-2.3.6.jar
into that directory.
3) Create a module.xml
file in the same directory with this content:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.codehaus.groovy">
<resources>
<resource-root path="groovy-all-2.3.6.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
</dependencies>
</module>
4) Modify the "urn:jboss:domain:ee:1.1" subsystem element in standalone.xml
(or whichever flavor you're using) to include the just-created module as a global module, e.g.
<subsystem xmlns="urn:jboss:domain:ee:1.1">
<spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
<jboss-descriptor-property-replacement>true</jboss-descriptor-property-replacement>
<global-modules>
<module name="org.codehaus.groovy" slot="main"/>
</global-modules>
</subsystem>
If it still doesn't work, it might require you to include myJar.jar
in the global module as well, although I'd also consider that a workaround.
Upvotes: 2