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
以前のセットアップでは、使用可能な ScriptEngineFactory として登録されていないエンジンとして Rhino を使用していましたが、クラスパスには「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;
クラスローダーの1つがJava 8 + OSGiでNashornを操作するための他の回避策を認識できるようにOSGiを構成する方法はありますか?