JDK-8057825 : emitted socket arg becomes null in avatar.js http tests
  • Type: Bug
  • Component: core-libs
  • Sub-Component: jdk.nashorn
  • Affected Version: 8u40
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2014-09-08
  • Updated: 2015-06-04
  • Resolved: 2014-11-05
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.
8u40 b15Fixed 9Fixed
A new regression has been identified in 8u40 b04. When running some of the http tests of avatar.js with this build of the jdk, emitted socket becomes undefined. For example, applying this diagnostic patch to http.js, and running the test test-http-timeout.js, we get this output -

@@ -1725,9 +1725,11 @@
 ClientRequest.prototype.onSocket = function(socket) {
+  print('ClientRequest.prototype.onSocket ' + socket + ' type ' + (typeof socket));
   var req = this;
   process.nextTick(function() {
+    print('ClientRequest.prototype.onSocket.nextTick ' + socket + ' type ' + (typeof socket));
     var parser = parsers.alloc();
     req.socket = socket;
     req.connection = socket;
@@ -1755,6 +1757,7 @@
     socket.onend = socketOnEnd;
     socket.on('close', socketCloseListener);
     parser.onIncoming = parserOnIncomingClient;
+    print('ClientRequest.prototype.onSocket.nextTick.emitting ' + socket + ' type ' + (typeof socket));
     req.emit('socket', socket);

java -jar dist/avatar-js.jar test/simple/test-http-timeout.js 
ClientRequest.prototype.onSocket [object Object] type object
ClientRequest.prototype.onSocket.nextTick [object Object] type object
ClientRequest.prototype.onSocket.nextTick.emitting [object Object] type object
Exception in thread "main" TypeError: Cannot read property "setTimeout" from undefined in jar:file:/home/akhil/ws/avatar-js/dist/avatar-js.jar!/lib/http.js at line number 1822
	at <anonymous> (jar:file:/home/akhil/ws/avatar-js/dist/avatar-js.jar!/lib/http.js:1822)
	at <anonymous> (jar:file:/home/akhil/ws/avatar-js/dist/avatar-js.jar!/lib/events.js:180)
	at <anonymous> (jar:file:/home/akhil/ws/avatar-js/dist/avatar-js.jar!/lib/events.js:117)
	at <anonymous> (jar:file:/home/akhil/ws/avatar-js/dist/avatar-js.jar!/lib/http.js:1761)

Note that 'socket' is not undefined when emitted at http.js:1761, but becomes undefined at line http.js:1822.

Perhaps the deep inheritance hierarchy is a factor? ClientRequest extends OutgoingMessage extends Stream extends EventEmitter.
I can repro this.

It seems like apply-to-call transformation in EventEmitter.prototype.once$g in src/main/js/lib/event.js:181 is incorrectly handled. Adding -Dnashorn.apply2call=false to the command line is a suggested workaround until this gets fixed.

This seems to be a reproducer: function createApplier(f) { function applier() { f.apply(this, arguments); } return applier; } function printer(x) { print(x); } var printerApplier = createApplier(printer); printerApplier(); printerApplier.apply(this, ["foo"]); Expected output is: undefined foo but it prints undefined undefined Setting -Dnashorn.apply2call=false will make it work correctly, further supporting the theory that the problem lies in apply2call. Also, if the method is not invoked first with less arguments, then it will work (so the initial parameterless invocation is essential for reproduction).