JDK から分離した ECMAScript エンジンの Nashorn を依存ライブラリで使用する

参考リンク。

環境

$ JAVA_HOME=$JAVA14_HOME mvn --version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: C:\Users\y_okazawa\.sdkman\candidates\maven\current
Java version: 14, vendor: AdoptOpenJDK, runtime: C:\Users\y_okazawa\scoop\apps\adopt14-hotspot\current
Default locale: ja_JP, platform encoding: UTF-8
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

$ JAVA_HOME=$JAVA15_HOME mvn --version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: C:\Users\y_okazawa\.sdkman\candidates\maven\current
Java version: 15.0.2, vendor: AdoptOpenJDK, runtime: C:\Users\y_okazawa\scoop\apps\adopt15-hotspot\current
Default locale: ja_JP, platform encoding: UTF-8
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

$ mvn --version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: C:\Users\y_okazawa\.sdkman\candidates\maven\current
Java version: 16, vendor: Oracle Corporation, runtime: C:\Users\y_okazawa\scoop\apps\openjdk16\current
Default locale: ja_JP, platform encoding: UTF-8
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

実験

プロジェクトの詳細は後述。

次の条件で、ただの Hello World ができることを確認しただけ。

  • OpenJDK 14/OpenJDK 15/OpenJDK 16について
    • 依存ライブラリ指定なしで実行
    • 依存ライブラリ指定ありで実行

結果は以下のとおり。

OpenJDK 依存ライブラリ指定の有無 結果
14 なし 動く
14 あり 動く
15 なし 動かない
15 あり 動く
16 なし 動かない
16 あり 動く
# OpenJDK 14, 依存ライブラリなし
$ JAVA_HOME=$JAVA14_HOME mvn clean compile exec:java -q -Djava.version=14 -Dexec.mainClass=com.example.nashorn.NashornAgain
Warning: Nashorn engine is planned to be removed from a future JDK release
Hello, World!
# OpenJDK 14, 依存ライブラリあり
$ JAVA_HOME=$JAVA14_HOME mvn clean compile exec:java -q -Pwith-dependency -Djava.version=14 -Dexec.mainClass=com.example.nashorn.NashornAgain
Hello, World!

# OpenJDK 15, 依存ライブラリなし
$ JAVA_HOME=$JAVA15_HOME mvn clean compile exec:java -q -Djava.version=15 -Dexec.mainClass=com.example.nashorn.NashornAgain
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.0.0:java (default-cli) on project nashorn-again: An exception occured while executing the Java class. Cannot invoke "javax.script.ScriptEngine.eval(String)" because "engine" is null -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
# OpenJDK 15, 依存ライブラリあり
$ JAVA_HOME=$JAVA15_HOME mvn clean compile exec:java -q -Pwith-dependency -Djava.version=15 -Dexec.mainClass=com.example.nashorn.NashornAgain
Hello, World!

# OpenJDK 16, 依存ライブラリなし
$ JAVA_HOME=$JAVA16_HOME mvn clean compile exec:java -q -Djava.version=16 -Dexec.mainClass=com.example.nashorn.NashornAgain
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.0.0:java (default-cli) on project nashorn-again: An exception occured while executing the Java class. Cannot invoke "javax.script.ScriptEngine.eval(String)" because "engine" is null -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
# OpenJDK 15, 依存ライブラリあり
$ JAVA_HOME=$JAVA16_HOME mvn clean compile exec:java -q -Pwith-dependency -Djava.version=16 -Dexec.mainClass=com.example.nashorn.NashornAgain
Hello, World!

実験した素材の説明

こういう配置の Maven プロジェクトを作成した。

pom.xml
src/main/java/com/example/nashorn/NashornAgain.java

pom.xml のレイアウトは以下。

  • JDKのバージョンは java.version を経由して maven.compiler.target に指定する
  • 依存ライブラリはプロファイル with-dependency に入れてる
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>nashorn-again</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>nashorn-again</name>
    <description>Demo project for Nashorn dependency</description>
    <properties>
        <java.version>16</java.version>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.release>${java.version}</maven.compiler.release>
    </properties>
    <profiles>
        <profile>
            <id>with-dependency</id>
            <dependencies>
                <dependency>
                    <groupId>org.openjdk.nashorn</groupId>
                    <artifactId>nashorn-core</artifactId>
                    <version>15.3</version>
                </dependency>
            </dependencies>
        </profile>
    </profiles>
</project>

コンパイル、実行してるコードはこれ。

package com.example.nashorn;

import javax.script.*;

public class NashornAgain {
    public static void main(String[] args) throws Exception {
        // create a script engine manager
        ScriptEngineManager factory = new ScriptEngineManager();
        // create a Nashorn script engine
        ScriptEngine engine = factory.getEngineByName("nashorn");
        // evaluate JavaScript statement
        try {
            engine.eval("print('Hello, World!');");
        } catch (final ScriptException se) { se.printStackTrace(); }
    }
}