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

3
我正在寻找一种解决方案,使Nashorn与Java 1.8及以上的所有版本兼容,正如我之前在另一个问题中提到的那样(请参见此问题)。
目前,我正在尝试捕获UnsupportedClassVersionError以确定系统是否能够像这样运行Java 15的独立Nashorn(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

我曾尝试通过反转之前的try/catch(加载Java < 15 Nashorn,如果不存在则加载独立版本)来捕获NoClassDefFoundError,但错误仍然存在。

编辑:看起来这个错误是由Java < 15 Nashorn本身抛出的。

3个回答

6

我是Nashorn的维护者!我刚刚发布了Nashorn 15.2,它与15.1.1完全相同,但现在是使用Java 11编译的。这意味着您现在可以在Java 11及以上版本中使用独立的Nashorn,而不必在小于15和大于等于15之间切换。我编写了一个页面来说明如何在同时存在内置和独立Nashorn的Java 11-14上使用它。


2
要试试这样的东西怎么样(抱歉,我不是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();
    }
}

1
JVM本身会抛出错误。它在catch块内部抛出,因为在旧版Nashorn的类加载过程中,由于某种原因(名称冲突?)它最终加载了一个来自独立Nashorn版本的类(NashornLinkerExporter),而该版本似乎也存在于类路径中,并且由于它是使用jvmTarget=15编译的,所以无法在早期的JVM中加载。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接