JDK-8044520 : Nashorn cannot execute node.js's express module
  • Type: Bug
  • Component: core-libs
  • Sub-Component: jdk.nashorn
  • Affected Version: 8u40
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2014-06-02
  • Updated: 2014-07-29
  • Resolved: 2014-06-03
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
8u20Fixed 9 b17Fixed
As mentioned on https://avatar-js.java.net/ page, currently JDK8 with nashorn cannot execute express module due problems related to changing __proto__ to undefined. The fix on the library side is simple:

node_modules/ejs/lib/ejs.js line 286	

- options.__proto__ = options.locals;
+ if (options.locals) options.__proto__ = options.locals;

yet we need to run existing node.js application without modification and as such I'd like to propose a fix on the Nashorn side as well.
Relevant sections of ES6 draft spec. are these: * [[SetPrototypeOf]] builtin https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ordinary-object-internal-methods-and-internal-slots-setprototypeof-v * Object.prototype.__proto__ special property: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-additional-properties-of-the-object.prototype-object * Object.setPrototypeOf function: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.setprototypeof * __proto__ property name in object initializers: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-__proto__-property-names-in-object-initializers

Executing the same code in chromium 34.0.1847.116 Ubuntu 14.04 aura (260972) seems to yield the same result: > function test(options) { var old = options.__proto__;var r = options.__proto__ = options.local; if (r !== undefined) throw 'Expecting undefined: ' + r; if (old !== options.__proto__) throw 'Proto should remain unchanged: ' + options.__proto__; return options;} undefined > test({}) Object {}

OK. If I got it right, setting undefined to __proto__ should be no-op. Here is the new test and fix.

As per ECMAScript spec. ES6 draft (https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.setprototypeof) step (3) says " If Type(proto) is neither Object nor Null, then throw a TypeError exception." So Object.setPrototypeOf should throw TypeError on undefined being passed as proto. But https://people.mozilla.org/~jorendorff/es6-draft.html#sec-set-object.prototype.__proto__ says this in step 3: 3. If Type(proto) is neither Object nor Null, then return undefined. So it appears that es6 draft expects undefined proto value to be *ignored*. i.e., attempting to set undefined as __proto__ value should result in a no-op. (not really setting any valid prototype). So, nashorn should be fixed to just ignore undefined __proto__ set (and not anything legal as proto including null)

With my patch I can execute sample #8 from http://www.manning-source.com/books/cantelon/code_Node.js.zip without problems.

Test showing the flawed JavaScript code and a brute force change in Nashorn to make the test succeed. I can envision that my fix is not polished enough, that it will be necessary to hide it behind some option like "--allow-undefined-proto". Let me know your preferences and I can polish the patch.