Java < 15 和 >= 15 的不同 Nashorn 引擎?

Different Nashorn engine for Java < 15 and >= 15?

我正在尝试为 Nashorn 找到一种解决方法,使其与 Java 从 1.8 开始的每个版本兼容,正如我之前问过的另一个 question 中所说的那样。
我目前正在尝试捕获 UnsupportedClassVersionError 以查明系统是否能够 运行 standalone Nashorn for Java 15 像这样(Kotlin 代码):

scriptEngine = try {
            
    // Java >= 15

    org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory().scriptEngine
} catch(e: UnsupportedClassVersionError) {

    // Java < 15

    @Suppress("DEPRECATION")
    jdk.nashorn.api.scripting.NashornScriptEngineFactory().scriptEngine
}

不过看起来好像没有发现错误。堆栈跟踪如下:

java.lang.UnsupportedClassVersionError: org/openjdk/nashorn/api/linker/NashornLinkerExporter has been compiled by a more recent version of the Java Runtime (class file version 59.0), this version of the Java Runtime only recognizes class file versions up to 55.0

我也尝试捕捉 NoClassDefFoundError 反转之前的 try/catch(加载 Java < 15 Nashorn,如果它不存在加载独立的)但错误是一样。

编辑:看起来错误是由 Java < 15 Nashorn 本身引发的。

这样的事情怎么样(抱歉,我不是 Kotlin 开发人员,所以很纯粹 Java):

public static ScriptEngine getJSScriptEngine() {
    if (Double.parseDouble(System.getProperty("java.specification.version")) < 15) {
        return new ScriptEngineManager().getEngineByName("js");
    } else {
        return new org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory()
            .getScriptEngine();
    }
}

JVM 本身抛出错误。它是从 catch 块内部抛出的,因为在 class 加载旧 Nashorn 期间出于某种原因(名称冲突?)最终从 stand 加载 class (NashornLinkerExporter) -单独版本的 Nashorn,它似乎也出现在 classpath 中,并且由于它是使用 jvmTarget=15 编译的,因此无法在早期的 JVM 中加载它。

对于 JVM<15,您需要从包中排除此库(通过构建工具创建单独的工件),或者至少从运行时 classpath 中排除。在这种情况下 NoClassDefFoundError 将从 try 块内部抛出,并且不会从 catch 块内部抛出任何错误。

这里是 Nashorn 维护者!我刚刚发布 Nashorn 15.2, which is identical to 15.1.1 but is now compiled with Java 11. This means you can now use standalone Nashorn with Java 11 and above and don't have to switch for < 15 and >= 15. I wrote a page to explain 如何在 Java 11-14 上使用它,其中内置和独立的 Nashorn 都存在。