Jorn Vernee
Jorn Vernee

Reputation: 33895

IntelliJ: Put some dependencies on the module path in non-modular application

I have a non-modular Java 15 application that depends on stand-alone Nashorn (as an example).

I have a maven project set up in Intellij with the Nashorn dependency:

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

And the following Main class to test with:

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!');");
    }    
}

Since my application is non-modular, I don't have a module-info.java file, and when running the main class (by clicking the green play button) Intellij puts my main class and all the dependencies on the class path:

"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

However, since Nashorn can only be used as a JPMS module, the program ends up failing with an 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)

It works if I run the program from the command line and put Nashorn and it's dependencies on the module path instead of the class path.

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

How can I tell IntelliJ to put Nashorn and it's dependencies on the module path, instead of the class path as well?

Upvotes: 2

Views: 1418

Answers (1)

Jorn Vernee
Jorn Vernee

Reputation: 33895

Unfortunately, there doesn't currently seem to be a way in Intellij to flag certain dependencies as being modular only, to have them put on the module path instead of the class path automatically.

But, you can make it work by manually adding the Nashorn jar and it's dependencies to the module path, as well as adding the org.openjdk.nashorn module, as additional VM options in the run configuration:

enter image description here

Here I've just copied the part of the class path from Intellij's run command that contained Nashorn and it's dependencies.

You might need to enable the "VM options" field in the form first by clicking on the "Modify options" link:

enter image description here

This makes the program run as expected, printing 'Hello, World!'. It looks like Intellij will still put these jars on the class path as well, but since the module path takes precedence over the class path this works any ways.

Upvotes: 3

Related Questions