我在使用Jboss中的GroovyScriptEngine移植Java独立程序时遇到问题。
我的程序启动groovy脚本,它需要加载动态类来启动它们。 它具有如下内容:
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);
在myJar.jar中,groovy脚本需要类,而不是由启动groovy scrits本身的java程序。 通过这种方式,它可以很好地工作:我只需要包含以下maven依赖项。
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.3.6</version>
</dependency>
如果我在资源适配器(JCA连接器)中移植我的代码,虽然我已经添加了所有必需的依赖项,但是当我这样做时:
final ScriptEngine scriptEngine = seManager.getEngineByName("groovy");
我收到NullPointerException。
如果我尝试手动提供ScriptEngineManager registerig groovy,例如:
...
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");
脚本被加载但类路径不包含myJar.jar中提供的额外类。 所以我得到一个ClassNotFoundException。 如果此类包含在资源适配器归档中,则它可以正常工作,因此脚本似乎只能看到资源适配器中包含的类。
您是否知道如何解决此问题,除了包括资源适配器上的所有额外类(当前woraround)。 非常感谢你。
答案 0 :(得分:2)
我之前没有遇到过这个特定的问题,但是我在获取JBoss部署的war文件以获取Groovy脚本引擎方面遇到了问题。我为解决我的问题所做的是创建一个全局Groovy模块:
1)创建目录$JBOSS_HOME/modules/org/codehaus/groovy/main/
2)将groovy-all-2.3.6.jar
复制到该目录中。
3)使用以下内容在同一目录中创建module.xml
文件:
<?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)修改&#34; urn:jboss:domain:ee:1.1&#34; standalone.xml
中的子系统元素(或您使用的任何风格)将刚刚创建的模块包含为全局模块,例如
<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>
如果它仍然不起作用,可能还需要您在全局模块中包含myJar.jar
,尽管我也认为这是一种解决方法。