这只影响 Ubuntu 吗?Rhino(Java SE 6 和 7 中的 JavaScript 引擎)在 String

Is this only affecting Ubuntu? Rhino (JavaScript engine in Java SE 6 and 7) producing ConsString where String expected?

本文关键字:中的 JavaScript 引擎 String SE Ubuntu 影响 Java Rhino      更新时间:2023-09-26

现在有一个 Ubuntu 错误报告,在撰写本文时尚未回复。(我仍然有兴趣知道是否有人在 Ubuntu 之外看到这种行为。

复制器,以及它已损坏和未损坏的某些版本

写了一个简短的复制器来说明这个问题,在向我报告的人使用的 Ubuntu Trusty 系统上。他给我发了这个结果摘要:

Fail  /usr/lib/jvm/java-6-openjdk-i386/jre/bin/java
Fail  /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java
Fail  /usr/lib/jvm/java-7-openjdk-i386/jre/bin/java
Pass  /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java 

(的,我没有追问他那些确切的版本,但他最近才从Ubunty Trusty存储库中安装了它们。7版本是1.7.0_95,正如他之前报道的那样。

我已经在Red Hat的这些版本上测试了相同的复制器,在任何地方都没有失败,所以这开始看起来像一些Ubuntu构建问题。

Pass  OpenJDK 1.6.0_38 (rhel-1.13.10.0.el6_7-x86_64)
Pass  OpenJDK 1.7.0_95 (rhel-2.6.4.0.el6_7-x86_64 u95-b00)
Pass  OpenJDK 1.8.0_71 (build 1.8.0_71-b15)

这是复制者。 Pass打印单个整数,通常为零(在echo不是ProcessBuilder可以启动的命令的平台上,它可能不为零)。 Fail是如下所示的例外:

javax.script.ScriptException: sun.org.mozilla.javascript.EvaluatorException: Java constructor for "java.lang.ProcessBuilder" with arguments "string,string,sun.org.mozilla.javascript.ConsString" not found.

安德...代码如下:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class jstest {
  public static void main(String[] args) throws Exception {
    ScriptEngineManager mgr = new ScriptEngineManager();
    ScriptEngine testEngine =
      mgr.getEngineByMimeType( "application/javascript");
    String testScript =
"    var key = 'something';'n" +
"    var tpr = 'echo';'n" +
"    var pb = new java.lang.ProcessBuilder(tpr, '--', '--'+key);'n" +
"    pb.start().waitFor();'n";
    System.out.println(testEngine.eval(testScript)); // success prints 0
  }
}
更新

的更新

这个问题的记者(对我)已经澄清说,他运行的是一个OpenJDK版本,而不是(正如我之前认为的那样)Oracle。它显然是OpenJDK 7。为 Ubuntu Trusted 打包。我从该JVM中运行的Maven日志的顶部推断其版本,该日志出现:

Java version: 1.7.0_95, vendor: Oracle Corporation

似乎我错误地假设那一定是 Oracle 的 1.7.0_95。(我不确定Maven选择哪些Java系统属性来创建该版本行,但是我已经要求他向我发送该JVM属性的完整列表,以便我可以学会不再犯该错误。

向可能尝试在 Oracle 1.7.0_95 中重现此问题的任何人表示歉意。

更新

我已经下载并尝试了JDK 1.7.0_80(这是Oracle付费支持客户可用的1.7系列的最新成员),并且JavaScript运行没有问题。

无论更改了什么更改,行为都必须出现在仅供 Oracle 支持客户使用的更高版本中。这可能有助于解释为什么它还没有被更广泛地注意到。

这些付费支持更新有发行说明,但到目前为止,在浏览它们时,我还没有看到明显的吸烟枪。(一些版本有指向"有关所有更改,请参阅此处"页面的链接,到目前为止,我还没有遵循这些页面。

回到最初的问题

我有一个小任务是在Java的JavaScript javax.script引擎中完成的,我知道它是基于Java SE 6和7中的Rhino,在Java SE 8中换成了Nashorn。知道这一点,我非常小心地在 6、7 和 8 上测试了它,并且需要进行一些调整才能使其与两个引擎一起使用,但当我完成时,它在任何地方都能完美运行。

今天,我收到了一封运行

Oracle Java OpenJDK 1.7.0_95(比我测试的版本更新)的人的电子邮件,它无法执行JavaScript。主要问题似乎是两个字符串之间的+运算符不再产生字符串结果,而是生成sun.org.mozilla.javascript.ConsString。它不像常规字符串那样(它缺少replace方法,将其作为参数传递给 Java 方法,期望 String 生成找不到的方法,因为签名错误等)如果我编辑并将每个字符串表达式s1 + s2更改为String(s1 + s2),那么我又有一个可用的字符串。

似乎还有另一种行为变化,因为这以前有效:

var pb = new java.lang.ProcessBuilder(pgc, '--'+key);

现在,当然,如果我将参数 2 更改为 String('--'+key) ,它会以这种方式失败:

javax.script.ScriptException: sun.org.mozilla.javascript.EvaluatorException: Java constructor for "java.lang.ProcessBuilder" with arguments "string,sun.org.mozilla.javascript.ConsString" not found.

所以我确实改变了它,但后来它仍然失败了,现在像这样:

javax.script.ScriptException: sun.org.mozilla.javascript.EvaluatorException: Java constructor for "java.lang.ProcessBuilder" with arguments "string,string" not found.

好的,所以ProcessBuilder有两个构造函数,一个声明接受List<java.lang.String>,一个可变参数(java.lang.String...),JavaScript引擎以前从未遇到过将此调用(及其两个字符串参数)映射到其中一个的问题。

对我来说,这些

似乎是已经悄悄出现的错误,比任何可能的故意更改脚本引擎都要多;这些新行为似乎不正确。我没有在最近的

Oracle JRE 7版本中做过一分为二,以准确找到它何时开始以这种方式运行。只有我一个人看到它吗?
也许回答

这个问题有点晚了,因为唯一随 Rhino 而不是 Nashorn 一起提供的 Java 版本已经过时了。在Java 14之后,甚至Nashorn也不再包含电池,尽管可以包含独立的Nashorn或GraalJS以在项目中使用JavaScript。

但回到犀牛。

JavaScript 本身的 Rhino 实现似乎并没有直接包含脚本引擎包装器,以便通过 javax.script API 提供。包装器是一个小小的额外编码工作。Oracle可能有一个不能直接用于OpenJDK的版本,或者在一个链接上已经失效(正如另一个StackOverflow问题所暗示的那样)。另一个可能是独立开发的,或者从旧代码开始(我手头没有所有细节)。这里至少有一个 Maven 分发的分叉,其中包含源代码。

像 Rhino ConsString的某些实例没有被制作成 Java String这样的问题存在于某些版本的引擎包装器中,这些版本包含在 OpenJDK 的某些版本中。它们并不代表Rhino本身的行为变化或回归。