Reputation: 1
Before updating from IBM Java 7 to 8 the following code used to work in an Equinox OSGi environment:
ScriptEngineManager manager = new ScriptEngineManager(getClass().getClassLoader());
ScriptEngine engine = manager.getScriptEngineManager().getEngineByExtension("js");
engine.eval("<... js code ...>");
((Invocable) engine).getInterface(MyInterface.class) // ECMAScript exception
In the previous setup I used Rhino as engine which is now not registered as available ScriptEngineFactory anymore but still on the classpath, only "Oracle Nashorn".
After updating to IBM Java 8 (including Nashorn) I get the following exception:
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 tries to check if the classloader of jdk.nashorn.internal.runtime.ScriptFunction (Ext ClassLoader) can load the given interface (Bundle ClassLoader) or vice versa via:
Class.forName(classBName, false, clazzA.getLoader()) == classB;
Any ideas how to configure OSGi to let one of the classloaders see the other or other workarounds for working with Nashorn on Java 8 + OSGi?
Upvotes: 0
Views: 675
Reputation: 11
The issue was not with the code. The issue was with the application server. I was using JBoss 6.4.0 Application Server, the issue was it did not have nashorn paths in module.xml file under EAP_HOME\modules\system\layers\base\sun\jdk\main. I added the missing nashorn paths to the module.xml file mentioned in the above path and it resolved my issue. You can also resolve the issue by using Jboss 7.0 as it has the nashorn paths by default.
Missing nashorn paths
<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"/>
Upvotes: 0
Reputation: 1084
According to Oracle Docs, you may initialize your engine like the following Example:
ScriptEngineManager engineManager = new ScriptEngineManager();
ScriptEngine engine = engineManager.getEngineByName("nashorn");
engine.eval(new FileReader("src/sample2/xyz.js"));
Invocable invocable = (Invocable) engine;
Upvotes: 0