Jboss 7中的GroovyScriptEngine类加载

时间:2014-09-05 14:52:24

标签: java groovy jboss

我在使用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)。 非常感谢你。

1 个答案:

答案 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,尽管我也认为这是一种解决方法。