0

在从 IBM Java 7 更新到 8 之前,以下代码用于在 Equinox OSGi 环境中工作:

ScriptEngineManager manager = new ScriptEngineManager(getClass().getClassLoader());
ScriptEngine engine = manager.getScriptEngineManager().getEngineByExtension("js");
engine.eval("<... js code ...>");
((Invocable) engine).getInterface(MyInterface.class) // ECMAScript exception

在之前的设置中,我使用 Rhino 作为引擎,它现在不再注册为可用的 ScriptEngineFactory,但仍在类路径中,只有“Oracle Nashorn”。

更新到 IBM Java 8(包括 Nashorn)后,出现以下异常:

    ECMAScript Exception: TypeError: Can not find a common class loader for ScriptObject and MyInterface.
        at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:69)
        at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:225)
        at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:197)
        at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:184)
        at jdk.nashorn.internal.runtime.linker.AdaptationResult.typeError(AdaptationResult.java:82)
        at jdk.nashorn.internal.runtime.linker.JavaAdapterFactory$AdapterInfo.getAdapterClass(JavaAdapterFactory.java:326)
        at jdk.nashorn.internal.runtime.linker.JavaAdapterFactory.getAdapterClassFor(JavaAdapterFactory.java:162)
        at jdk.nashorn.internal.runtime.linker.JavaAdapterFactory.getAdapterClassFor(JavaAdapterFactory.java:148)
        at jdk.nashorn.internal.runtime.linker.JavaAdapterFactory.getConstructor(JavaAdapterFactory.java:202)
        at jdk.nashorn.api.scripting.NashornScriptEngine.getInterfaceInner(NashornScriptEngine.java:291)
        at jdk.nashorn.api.scripting.NashornScriptEngine.getInterface(NashornScriptEngine.java:216)
        ...

Nashorn 尝试通过以下方式检查 jdk.nashorn.internal.runtime.ScriptFunction (Ext ClassLoader) 的类加载器是否可以加载给定的接口 (Bundle ClassLoader),反之亦然:

Class.forName(classBName, false, clazzA.getLoader()) == classB;

任何想法如何配置 OSGi 以让其中一个类加载器看到在 Java 8 + OSGi 上使用 Nashorn 的其他或其他解决方法?

4

2 回答 2

0

问题不在于代码。问题出在应用程序服务器上。我使用的是 JBoss 6.4.0 应用服务器,问题是它在 EAP_HOME\modules\system\layers\base\sun\jdk\main 下的 module.xml 文件中没有 nashorn 路径。我将缺少的 nashorn 路径添加到上述路径中提到的 module.xml 文件中,它解决了我的问题。您还可以使用 Jboss 7.0 解决此问题,因为它默认具有 nashorn 路径。

缺少 nashorn 路径

                <path name="jdk/nashorn/api/scripting"/>
                <path name="jdk/nashorn/api/scripting/resources"/>
                <path name="jdk/nashorn/internal/codegen"/>
                <path name="jdk/nashorn/internal/codegen/types"/>
                <path name="jdk/nashorn/internal/ir"/>
                <path name="jdk/nashorn/internal/ir/annotations"/>
                <path name="jdk/nashorn/internal/ir/debug"/>
                <path name="jdk/nashorn/internal/ir/visitor"/>
                <path name="jdk/nashorn/internal/lookup"/>
                <path name="jdk/nashorn/internal/objects"/>
                <path name="jdk/nashorn/internal/objects/annotations"/>
                <path name="jdk/nashorn/internal/parser"/>
                <path name="jdk/nashorn/internal/runtime"/>
                <path name="jdk/nashorn/internal/runtime/arrays"/>
                <path name="jdk/nashorn/internal/runtime/linker"/>
                <path name="jdk/nashorn/internal/runtime/options"/>
                <path name="jdk/nashorn/internal/runtime/regexp"/>
                <path name="jdk/nashorn/internal/runtime/regexp/joni"/>
                <path name="jdk/nashorn/internal/runtime/resources"/>
                <path name="jdk/nashorn/internal/runtime/resources/fx"/>
                <path name="jdk/nashorn/internal/runtime/scripts"/>
                <path name="jdk/nashorn/internal/tools"/>
                <path name="jdk/nashorn/internal/tools/resources"/>
                <path name="jdk/internal/dynalink"/>
                <path name="jdk/internal/dynalink/beans"/>
                <path name="jdk/internal/dynalink/linker"/>
                <path name="jdk/internal/dynalink/support"/>
于 2016-12-08T22:23:30.703 回答
0

根据 Oracle Docs,您可以像以下示例一样初始化引擎:

ScriptEngineManager engineManager = new ScriptEngineManager();
    ScriptEngine engine = engineManager.getEngineByName("nashorn");
    engine.eval(new FileReader("src/sample2/xyz.js"));
    Invocable invocable = (Invocable) engine;
于 2016-07-22T10:08:49.227 回答