如何在Java 15及更高版本中使用Nashorn?

2022-09-02 00:33:18

我有一个现有的Spring Boot应用程序,它是非模块化的,并使用Nashorn。该应用程序在Java 14上运行良好。

添加可用于 Java 15 的新 Nashorn 的 Maven 坐标后,应用程序在启动脚本引擎时失败。

public static void main(String[] args) throws ScriptException {
    ScriptEngineManager factory = new ScriptEngineManager();
    ScriptEngine engine = factory.getEngineByName("nashorn"); 
    engine.eval("print('Hello, World!');");
} 

错误信息:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "javax.script.ScriptEngine.eval(String)" because "engine" is null
    at xxxxx.yyyy.service.JavaScriptServiceImpl.main(JavaScriptServiceImpl.java:52)

是否需要模块化整个项目以利用Nashorn?


答案 1

根据JEP 372,Nashorn已从JDK 15中删除,但您可以从 https://search.maven.org/artifact/org.openjdk.nashorn/nashorn-core/15.0/jar

对于 Maven,请将以下依赖项包含在您的pom.xml

<dependency>
  <groupId>org.openjdk.nashorn</groupId>
  <artifactId>nashorn-core</artifactId>
  <version>15.0</version>
</dependency>

对于 Gradle,请将下面的依赖项包含在您的build.gradle

implementation 'org.openjdk.nashorn:nashorn-core:15.0'

不幸的是,独立 Nashorn 只能用作 JPMS 模块。因此,您可能需要遵循 https://stackoverflow.com/a/46289257 中所述的解决方案,以使其与非模块化应用程序配合使用。

从给定的类中,根据来自@JornVernee和@AttilaSzegedi的反馈,命令行应如下所示xxxxx.yyyy.service.JavaScriptServiceImpl

jdk-15.0.1/bin/java -classpath /home/nashorn-helloworld/target/classes --module-path /home/org/openjdk/nashorn/nashorn-core/15.0:/home/org/ow2/asm/asm/7.3.1:/home/org/ow2/asm/asm-analysis/7.3.1:/home/org/ow2/asm/asm-commons/7.3.1:/home/org/ow2/asm/asm-tree/7.3.1/home/org/ow2/asm/asm-util/7.3.1 --add-modules org.openjdk.nashorn xxxxx.yyyy.service.JavaScriptServiceImpl

答案 2

我刚刚发布了Nashorn 15.1,这使得Nashorn在通过类路径而不是通过模块路径加载时可以正常工作。我用我自己的一个小Spring Boot应用程序测试了它,它的工作原理。


推荐