1

我有一个依赖于独立 Nashorn的非模块化 Java 15 应用程序(例如)。

我在 Intellij 中设置了一个带有 Nashorn 依赖项的 maven 项目:

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

以及以下Main要测试的类:

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

由于我的应用程序是非模块化的,因此我没有module-info.java文件,并且在运行主类时(通过单击绿色播放按钮)Intellij 将我的主类和所有依赖项放在类路径上:

"C:\Program Files\Java\jdk-15\bin\java.exe" "-javaagent:J:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.1.1\lib\idea_rt.jar=53813:J:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.1.1\bin" -Dfile.encoding=UTF-8 -classpath "H:\WS-new\non-modular nashorn\target\classes;C:\Users\Jorn\.m2\repository\org\openjdk\nashorn\nashorn-core\15.0\nashorn-core-15.0.jar;C:\Users\Jorn\.m2\repository\org\ow2\asm\asm\7.3.1\asm-7.3.1.jar;C:\Users\Jorn\.m2\repository\org\ow2\asm\asm-commons\7.3.1\asm-commons-7.3.1.jar;C:\Users\Jorn\.m2\repository\org\ow2\asm\asm-analysis\7.3.1\asm-analysis-7.3.1.jar;C:\Users\Jorn\.m2\repository\org\ow2\asm\asm-tree\7.3.1\asm-tree-7.3.1.jar;C:\Users\Jorn\.m2\repository\org\ow2\asm\asm-util\7.3.1\asm-util-7.3.1.jar" main.Main

但是,由于Nashorn 只能用作 JPMS 模块,因此程序最终以 NPE 失败:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "javax.script.ScriptEngine.eval(String)" because "engine" is null
    at main.Main.main(Main.java:12)

如果我从命令行运行程序并将 Nashorn 及其依赖于模块路径而不是类路径,它就可以工作。

java -classpath <dir with Main class> --module-path <nashorn jars> --add-modules org.openjdk.nashorn main.Main

我如何告诉 IntelliJ 将 Nashorn 及其依赖项放在模块路径上,而不是类路径上?

4

1 回答 1

2

您可以通过手动添加 Nashorn jar 及其对模块路径的依赖项以及添加org.openjdk.nashorn模块来使其工作,作为运行配置中的附加 VM 选项:

在此处输入图像描述

在这里,我刚刚从 Intellij 的运行命令中复制了包含 Nashorn 及其依赖项的部分类路径。

您可能需要首先通过单击“修改选项”链接来启用表单中的“VM 选项”字段:

在此处输入图像描述

这使程序按预期运行,打印“Hello, World!”。看起来 Intellij 仍然会将这些 jars 放在类路径上,但是由于模块路径优先于类路径,因此任何方式都可以。

不幸的是,Intellij 目前似乎没有办法将某些依赖项标记为仅是模块化的,让它们自动放在模块路径而不是类路径上。

于 2020-12-12T17:30:17.530 回答