当前位置: 首页 > 知识库问答 >
问题:

如何在Java15及以后使用Nashorn?

欧盛
2023-03-14

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

添加Java15可用的新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?

共有3个答案

松茂实
2023-03-14

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

訾高飞
2023-03-14

这里是纳肖恩维修工。

springboot没有将Nashorn作为JPMS模块加载,这确实是一个问题。Nashorn将自己导出为脚本引擎,由javax找到。剧本ScriptEngineManager通过其模块信息中的“提供”条目执行。java。它不使用旧的、非模块化的导出机制,即通过JAR文件中的相关META-INF/services/…条目声明自己。这意味着,如果JAR没有作为JPMS模块加载,脚本引擎管理器将不会发现它。(注意:即使它冗余了META-INF/services条目,也不会有什么帮助,因为Nashorn依赖于作为模块加载;作为JDK附带的代码,它从Java 9开始就是一个模块……现在要撤销它有些困难。)

我创建了一个小型测试应用程序,证实了这一点。我试图招募一些在Boot工作的人来帮助我弄清这件事。这很复杂,因为Boot创建了一个胖JAR文件,并将其所有依赖项打包到其中,然后管理它们的加载,所以你不能在启动时“仅仅”自己修改模块路径。

希望有一种方法可以告诉Boot将依赖项作为模块加载;到目前为止,我试图通过谷歌找到它的努力还没有取得成果。

隆礼骞
2023-03-14

根据JEP372,Nashorn已从JDK15中删除,但您可以从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,在构建中包含以下依赖项。渐变

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

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

从给定的类xxxxx。yyyy。服务JavaScriptServiceImpl并且根据@jornverne和@AttilaSzegedi的反馈,命令行应该如下所示

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
 类似资料:
  • 在我的Java应用程序中,一个很重要的功能是能够根据音频文件的元数据(例如,album/artist-title)重命名音频文件,并且使用Javascript指定掩码,这使得重命名功能非常灵活和强大。 我知道Javascript被弃用了,但现在看来它实际上将从Java15以后被删除。这种功能的丧失对我来说可能是一个主要问题,所以我问,即使它被正式删除,我是否有办法在Java 15应用程序中继续使用

  • 问题内容: 我是Angular 4的新手,所以谁能解释在Angular 4中的使用方式和位置? 实际上,我想从父组件覆盖子组件的某些CSS属性。此外,它在IE11上受支持吗? 问题答案: 通常, 可使用组合器将样式强制降低到 。这个选择器有一个别名>>>,现在还有另一个叫做:: ng-deep的别名。 由于 已弃用,建议使用 例如: 和 它将应用于子组件

  • 问题内容: 我正在阅读一些有关Java中异常处理的内容,以便能够编写更好的代码。好吧,我承认,我有罪。我使用了太多try-catch {}块,在捕获中使用了它,甚至没有使用适当的记录器(实际上是和被重定向到,因此生成了日志)。但是,经过几个小时的阅读,我发现自己在一个陌生的地方:未知。如果异常被设计为传递有关异常流状态的信息,那么人们如何知道WHERE是使用该信息执行操作的适当级别? 例如,当发生

  • 问题内容: 我参与开发一个Java项目,该项目使用一些C ++组件,因此我需要Jacob.dll。(在Windows 7上) 无论我把Jacob.dll放在哪里,我都在不断获取。 我在寻找可能的决定,而到目前为止尚未尝试的决定是设置LD_LIBRARY_PATH变量,指向.dll文件。 我经验不足,不熟悉该变量的含义和用法-您能帮我吗? 问题答案: 通常,您必须在JVM的命令行上进行设置:

  • 问题内容: 我已经阅读了很多有关@JoinColumn的内容,但是我仍然不明白它的含义。 患者表 车辆表 患者分类 车辆类别 Vehicle Class ---- Entity @JoinColumn(name=”patient_id”) ---- annotation private Patient patient ----field ``` 会说吗?该车辆实体有一个外键到患者实体命名patie

  • 问题内容: 我是Flask的新手。我不明白怎么用。我在某处读到它用于返回查询字符串的值[如果我错了,请纠正我]。以及需要多少个参数。我知道当我必须存储提交的表单数据时,我可以使用 在此,仅传递一个参数。 考虑下面的代码。分页也已在此代码中完成。 在这里,request.args.get()采用两个参数。请解释为什么要使用两个参数以及它的用途。 问题答案: 根据flask.Request.args文