JDK-8047764 : Indexed or polymorphic set on global affects Object.prototype
  • Type: Bug
  • Component: core-libs
  • Sub-Component: jdk.nashorn
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2014-06-21
  • Updated: 2015-06-04
  • Resolved: 2014-09-22
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.
8u40Fixed 9 b33Fixed
When working with latest version of Nashorn I noticed a regression. Code that used to work on 1.8.0_05-b13 does not work on home made build from 847387339a56 tag jdk8u20-b18. To reproduce

$ hg clone http://source.apidesign.org/hg/html~html4j/
$ cd html~html4j
$ hg up -C 444b861dc45a
$ mvn clean install

this passes OK on 1.8.0_05-b13 (my default VM), but when I execute it as

JAVA_HOME=/build-jdk8u20-b18/linux-x86_64-normal-server-release/images/j2sdk-image mvn clean install -Djfxrt.jar=/usr/lib/jvm/java-8-oracle/jre/lib/ext/jfxrt.jar 

there is a ClassCastException:

java.lang.ClassCastException: jdk.nashorn.api.scripting.ScriptObjectMirror cannot be cast to [Ljava.lang.Object;
        at org.netbeans.html.ko4j.Knockout.allocJS(Knockout.java)

I will investigate the details, but clearly something changed significantly and I feel I should report that as soon as possible.

Revision c1f651636d9c fixes my problem. Thanks.

I changed the title from "Regression in Nashorn return value between 1.8.0_05-b13 and jdk8u20-b18" to "Indexed or polymorphic set on global affects Object.prototype".

Thanks for the extended reproducer, Jaroslav. I tracked the problem down to a bug in our scope setter code that causes toString to be set in Object.prototype instead of the global scope.

I tried to run the test on jdk9/nashorn$ hg id 45a09ce8502e tip and it is still broken. Have you tried the attached sample? I guess not, maybe it is hard to configure. I am attaching a ZIP file with ant project showing the issue. Please, download it and try it: $ wget https://bugs.openjdk.java.net/secure/attachment/22307/brokennashorn.zip $ unzip brokennashorn.zip $ cd brokennashorn/ $ ant run -Dplatforms.JDK_1.9.home=/usr/lib/jvm/java-8-oracle/ run: [java] [ Envjs/1.6 (Nashorn; U; Linux i386 3.11.0-12-generic; en-US; rv:0.1) Resig/20070309 PilotFish/1.2.13 ] [java] name: Java HotSpot(TM) Server VM [java] spec: 1.8 [java] spec: 1.8 [java] vendor: Oracle Corporation [java] version: 25.11-b03 $ ant run -Dplatforms.JDK_1.9.home=/home/jtulach/src/jdk9/build/linux-x86-normal-server-release/images/j2sdk-image/ run: [java] [ Envjs/1.6 (Nashorn; U; Linux i386 3.11.0-12-generic; en-US; rv:0.1) Resig/20070309 PilotFish/1.2.13 ] [java] name: OpenJDK Server VM [java] spec: 1.9 [java] spec: 1.9 [java] vendor: Oracle Corporation [java] version: 1.9.0-internal-jtulach_2014_09_15_14_10-b00 [java] Exception in thread "main" java.lang.IllegalStateException: Expecting 128: -1 [java] at nashornproblems.ArraysTest.main(ArraysTest.java:77) [java] Java Result: 1

Could be that this is the dupe of my apply fix. Does it work with the latest nine?

If you include the env.nashorn.1.2-debug.js in your application next to the ArraysTest class, and make sure it is evaluated you'll see the difference between JDK8_11 and JDK8 recent. This is the code I used to load the env.js: InputStream is = ArraysTest.class.getResourceAsStream("env.nashorn.1.2-debug.js"); ENG.eval(new InputStreamReader(is, "UTF-8")); is.close(); The main method succeeds on JDK1.8 25.11-b03, but fails on the recent build 25.20-b19. You can get the version of env.js from here http://hg.netbeans.org/html4j/raw-file/e4dad7683970/boot-script/src/test/resources/net/java/html/boot/script/ko4j/env.nashorn.1.2-debug.js or from JDK-8006183.

ArraysTest.java is a simplified sample showing what is going on. However the problem is not in this file itself, it turns out that one needs to include env.js implementation http://hg.netbeans.org/html4j/log/5cdbf639fa7c/boot-script/src/test/resources/net/java/html/boot/script/ko4j/env.nashorn.1.2-debug.js which is taken from JDK-8006183 For some reason evaluation of Object.prototype.toString.call(arr) on an [object Array] ends up in env.js line 23870 and returns [Window].

It is also possible to put breakpoint to http://source.apidesign.org/hg/html~html4j/file/444b861dc45a/boot-script/src/main/java/net/java/html/boot/script/ScriptPresenter.java#l267 - it should be visible what code is being sent to ScriptEngine and what results one gets.

Maybe, since it's a codegen error, the method can be extracted to a smaller reproducer. Typically these verify errors have to do with generated method shape and many of them translate into still being problems if you just try to compile to code outside its environment *fingers crossed*

Jaroslav, the error is happening in org.netbeans.html.ko4j.Knockout.allocJS which is a native method. I don't see where it is implemented, and how it gets to the code you posted in your first comment. Can you help me along please?

Just put a breakpoint to nashorn code and it should get stopped. It should be relatively easy to open and debug individual tests from inside of NetBeans IDE. The allocJS internal implementation is in JavaScript, its code is in @JavaScriptBody(body="..."). More information is at: http://bits.netbeans.org/html+java/0.8.2/net/java/html/js/package-summary.html

As discussed.

Sundar - can you look at this? I hadn't seen it hasn't been updated do to assigne still being Jaroslav

Any update? I am trying to verify JDK-8046013, but my project does not run at all because of this issue.

I am sorry. Please use http protocol instead, it works the same for read access: http://source.apidesign.org/hg/html~html4j/

hg clone https://source.apidesign.org/hg/html~html4j/ wants username and password credentials. What should we give it ?

Weird. At least we can exclude optimistic typing from the possible culprits as it isn't in 8u20.

The code that misbehaves is var atype = Object.prototype.toString.call(arr); if (atype === '[object Array]') return arr.length; else return -1; the "arr" arguments is NativeArray of length 128. For some reason it seems that in the jdk8u20-b18 the value of atype is "[object window]" rather than "[object array]".