如何在 Nashorn 中追踪 ReferenceError

How to track down a ReferenceError in Nashorn

我遇到了一个问题,看起来它可能是 Nashorn 引擎中的某种错误,但我想不出一个好的方法来提炼一个可以证明它的测试用例。

我有一段代码(曾经有效!)大致如下所示:

'use strict';
function Dummy() {
  this.val = 'I am fubar';
  this.aContainer = [];
}
Dummy.prototype.toString = function() { return JSON.stringify(this);};

let obj = {};
obj.aMethod = function(arg) {
  let fubar = new Dummy();
  print('Okay so far');

  fubar.aContainer.push({"some":"thing"});
  print('Still okay');
  fubar.aContainer.push({"==": [{"var": "something_else"}, fubar.val]});

  return fubar;
};

print(obj.aMethod(null));

不幸的是,运行 这个带有 jss --language=es6 -strict 的例子没有崩溃。不过在我的真实代码中,我得到以下内容:

jdk.nashorn.internal.runtime.ECMAException: ReferenceError: "fubar" is not defined

如果我按如下方式更改代码,它运行良好:

'use strict';
function Dummy() {
  this.val = 'I am fubar';
  this.aContainer = [];
}
Dummy.prototype.toString = function() { return JSON.stringify(this);};

let obj = {};
obj.aMethod = function(arg) {
  let fubar = new Dummy();
  print('Okay so far');

  fubar.aContainer.push({"some":"thing"});
  print('Still okay');
  let x = fubar.val;
  fubar.aContainer.push({"==": [{"var": "something_else"}, x]});

  return fubar;
};

print(obj.aMethod(null));

我能做些什么来尝试进一步检测真实代码或以其他方式追踪这个问题吗?奇怪的是错误发生在执行的早期。如果我在方法中的任何地方调用 print() ,则永远不会打印。我在调用堆栈中的代码的最后一行实际上是调用该方法的行。

我刚刚通过自动更新获取了 Java 的新版本,但我需要查看此代码是否在 运行 下面。我当前的控制台版本是:

➜  ~ java -version
java version "1.8.0_77"
Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)

本文档中包含对跟踪 Nashorn 的所有操作的完整摘要:

jdk8u-dev/nashorn/file/tip/docs/DEVELOPER_README

它描述了用于内部调试和检测目的的系统属性,以及用于相同目的的系统记录器。