Nashorn ScriptEngine 不是 found/registered 在 Karaf+Felix (openJDK)
Nashorn ScriptEngine not found/registered at Karaf+Felix (openJDK)
我在 Karaf+Felix+OpenJDK8 环境中加载 nashorn 脚本引擎时遇到问题:new ScriptEngineManager().getEngineByName("nashorn")
returns null
在该环境中。我使用该代码的测试成功通过,无论是由 Maven 执行(在 tje Linux/Debian 服务器上安装相同的 JDK 还是在我的 Windows 机器上的 IDE 中执行.
这些是我检查的步骤:
Karaf 使用 JDK8 运行并引用了正确的 ext 目录:
> 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 ...
可用nashorn.jar:
> jar -tf /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/nashorn.jar | grep NashornScriptEngineFactory
jdk/nashorn/api/scripting/NashornScriptEngineFactory.class
在 <karaf>/etc/config.properties
org.osgi.framework.bootdelegation
属性 包含 jdk.nashorn.*
根据
我的bundle也imports/requires jdk.nashorn
被felix成功解析:
> 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]
...
顺便说一下,new ScriptEngineManager().getEngineFactories()
返回的列表是空的,因此无法尝试其他脚本引擎。
有人知道哪里出了问题吗?在重新启动 karaf 之前我需要清除一些缓存吗?
ScriptEngineManager 的默认构造函数使用具有服务加载器机制的线程上下文class 加载器。如果您的线程上下文 class 加载器没有委托给扩展 class 加载器,那么将找不到 nashorn 或任何其他仅对扩展加载器可见的引擎!有两种解决方案:
- 您可以临时将线程上下文 class 加载器设置为扩展加载器或委托给它的加载器 - 就在创建 ScriptEngineManager 对象之前(并且您设置重置旧线程上下文 class 加载器找到引擎后)。
- 您可以通过传递适当的 ClassLoader 使用 ClassLoader 接受 ScriptEngineManager 的构造函数(另请参阅:https://docs.oracle.com/javase/8/docs/api/javax/script/ScriptEngineManager.html#ScriptEngineManager-java.lang.ClassLoader-)。同样,您可以传递扩展 class 加载器或任何委托给扩展 class 加载器的加载器 - 这样扩展加载器可见的引擎可以通过服务加载器机制找到。
我在 Karaf+Felix+OpenJDK8 环境中加载 nashorn 脚本引擎时遇到问题:new ScriptEngineManager().getEngineByName("nashorn")
returns null
在该环境中。我使用该代码的测试成功通过,无论是由 Maven 执行(在 tje Linux/Debian 服务器上安装相同的 JDK 还是在我的 Windows 机器上的 IDE 中执行.
这些是我检查的步骤:
Karaf 使用 JDK8 运行并引用了正确的 ext 目录:
> 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 ...可用nashorn.jar:
> jar -tf /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/nashorn.jar | grep NashornScriptEngineFactory
jdk/nashorn/api/scripting/NashornScriptEngineFactory.class在
<karaf>/etc/config.properties
org.osgi.framework.bootdelegation
属性 包含jdk.nashorn.*
根据我的bundle也imports/requires
jdk.nashorn
被felix成功解析:> 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]
...
顺便说一下,new ScriptEngineManager().getEngineFactories()
返回的列表是空的,因此无法尝试其他脚本引擎。
有人知道哪里出了问题吗?在重新启动 karaf 之前我需要清除一些缓存吗?
ScriptEngineManager 的默认构造函数使用具有服务加载器机制的线程上下文class 加载器。如果您的线程上下文 class 加载器没有委托给扩展 class 加载器,那么将找不到 nashorn 或任何其他仅对扩展加载器可见的引擎!有两种解决方案:
- 您可以临时将线程上下文 class 加载器设置为扩展加载器或委托给它的加载器 - 就在创建 ScriptEngineManager 对象之前(并且您设置重置旧线程上下文 class 加载器找到引擎后)。
- 您可以通过传递适当的 ClassLoader 使用 ClassLoader 接受 ScriptEngineManager 的构造函数(另请参阅:https://docs.oracle.com/javase/8/docs/api/javax/script/ScriptEngineManager.html#ScriptEngineManager-java.lang.ClassLoader-)。同样,您可以传递扩展 class 加载器或任何委托给扩展 class 加载器的加载器 - 这样扩展加载器可见的引擎可以通过服务加载器机制找到。