Reputation: 11
I recently upgraded my java version from java 1.7 to java 1.8. After the upgrade i am getting this error.
Caused by: ECMAScript Exception: Type Error: Can not find a common class loader for ScriptObject and My Interface.
Please help me fix this issue.
Below is my method
private final ScriptEngine engine;
ScriptEngineManager sem = new ScriptEngineManager();
engine = sem.getEngineByName("nashorn");
public <K> K getNewInterface(MyScript myScript){
ScriptContext ctx = new SimpleScriptContext();
String script = myScript.getScript();
if(Strings.isEmpty(script)) {markInvalid(myScript, "Script is empty", null); return null;}
script += " (function(){return this;})();";
Object thiz;
try{
thiz = engine.eval(script, ctx);
} catch (ScriptException e){
markInvalid(myScript, "Can't execute script", e);
return null;
}
if(thiz==null) {markInvalid(myScript, "Script executed, but context is null", null); return null;}
K ret = (K) ((Invocable)engine).getInterface(thiz, myScript.getScriptInterfaceClass());
if(ret==null) {
markInvalid(myScript, "Script executed, but it's incompatible with required interface", null);
return null;
}else{
myScript.setValid(true);
return ret;
}
}
Upvotes: 0
Views: 1041
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: 4595
In order for Nashorn to crete an implementation of your interface, it must create (at runtime) a new class that both extends ScriptObject
(Nashorn's internal native JS object representation) and your interface (let's say it's named MyInterface
).
Such a class can only be created in the JVM if there's a class loader that can resolve both ScriptObject
and MyInterface
. Since ScriptObject
normally exists in the ext classpath (jre/lib/ext
) (in Java 8), you need to ensure that the class loader for MyInterface
has the so-called "ext class loader" in its parent class loader chain. This is normally true, as most code is loaded by the JVM app class loader. If you have a more elaborate class loader setup (e.g. you're in some kind of an app container), it might not be true.
Basically, see if this works (I presume there's no security manager around…):
ClassLoader myClassLoader = myScript.getScriptInterfaceClass().getClassLoader();
Class.forName("jdk.nashorn.internal.runtime.ScriptObject", true, myClassLoader);
If it throws a ClassNotFoundException
, you need to find out why doesn't myClassLoader
see the ScriptObject
class.
Upvotes: 1