I have a problem loading the nashorn script engine in a Karaf+Felix+OpenJDK8 environment: new ScriptEngineManager().getEngineByName("nashorn")
returns null
in that environment. My tests that use that code pass successfully, no matter if executed by maven (with the same JDK Installation at tje Linux/Debian server) or inside the IDE on my Windows machine.
These are the steps I checked:
Karaf runs with JDK8 having the correct ext directory referenced:
> ps aux | grep karaf | grep java
... -Djava.ext.dirs=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext:/usr/lib/jvm/java-8-openjdk-amd64/lib/ext:/media/sf_Development/app/apache-karaf-4.0.6/lib/ext ...
The nashorn.jar is available:
> jar -tf /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/nashorn.jar | grep NashornScriptEngineFactory
jdk/nashorn/api/scripting/NashornScriptEngineFactory.class
At <karaf>/etc/config.properties
the org.osgi.framework.bootdelegation
property contains jdk.nashorn.*
according to this question
My bundle also imports/requires jdk.nashorn
which is resolved by felix successfully:
> bundle:requirements my-bundle | grep -A 1 nashorn
...
osgi.wiring.package; (osgi.wiring.package=jdk.nashorn) resolved by:
osgi.wiring.package; jdk.nashorn 0.0.0 from org.apache.felix.framework [0]
...
By the way the list returned by new ScriptEngineManager().getEngineFactories()
is empty, so it's not an option to try another script engine.
Has someone any idea what went wrong? Did I need to clear some cache before restarting karaf?
ScriptEngineManager's default constructor uses the thread context class loader with service loader mechanism. If your thread context class loader does not delegate to the extension class loader, then nashorn or any other engine visible only to extension loader will not be found! There are two solutions: