JDK-8072596 : Arrays.asList results in ClassCastException with a JS array
  • Type: Bug
  • Component: core-libs
  • Sub-Component: jdk.nashorn
  • Affected Version: 8u40
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2015-02-05
  • Updated: 2017-08-09
  • Resolved: 2017-08-09
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.
8u60Fixed 9Fixed
Related Reports
Relates :  
File: list_conversion.js

Arrays = java.util.Arrays;
print(Arrays.asList("hello world".split(' ')));

The above script works fine with jdk8u31 but fails on jdk8u40 early access build and jdk9 with the following stack trace:

Exception in thread "main" java.lang.ClassCastException: Cannot cast jdk.nashorn.api.scripting.ScriptObjectMirror to [Ljava.lang.Object;
	at java.lang.invoke.MethodHandleImpl.newClassCastException(MethodHandleImpl.java:361)
	at java.lang.invoke.MethodHandleImpl.castReference(MethodHandleImpl.java:356)
	at jdk.nashorn.internal.scripts.Script$list_conversion.:program(list_conversion.js:2)
	at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:636)
	at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:229)
	at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:387)
	at jdk.nashorn.tools.Shell.apply(Shell.java:394)
	at jdk.nashorn.tools.Shell.runScripts(Shell.java:323)
	at jdk.nashorn.tools.Shell.run(Shell.java:169)
	at jdk.nashorn.tools.Shell.main(Shell.java:133)
	at jdk.nashorn.tools.Shell.main(Shell.java:112)

In a discussion with the team we reached a consensus not to pursue this for inclusion in 8u40.

Arrays.asList() seems to be an issue with us now always wrapping JS objects into ScriptObjectMirror since JDK-8050977. We can no longer take the path where we convert a NativeArray to Object[] as we don't see a NativeArray, we see a ScriptObjectMirror. Actually, with JDK-8068573 I had to fix recently (with POJO setters invoked using []) I also had to work around our tendency to now eagerly wrap ScriptObject into mirrors ��� it struck me as somewhat unnatural that asType for a parameter type from Object to Object is not identity but a wrapper creation instead. It starts to feel like we solved this problem at the wrong level with NashornBeansLinker.asType(). We should rather let every possible conversion take place first, and then at the very end if we have Objects being passed into a method handle that doesn't come from our linker, then apply wrapping. Of course, in method handle world this means that we should add wrapping filters immediately to POJO direct method handles, as returned by SingleDynamicMethod.getTarget() and then combine them further. Because of the opposite direction of composition vs. execution this'll make sure that the wrapping filter sits closest to the POJO direct method handle, and only kicks in as a last resort if no other conversion did anything else to the JS object parameter (e.g. converted a NativeArray to Object[]). So I think that the correct way to solve this is to ensure target method handles in SingleDynamicMethod get these filters. This way they will be applied at the lowest level and won't mess up other conversions nor will they affect overloaded method selection etc. This means a new customization point in Dynalink, though. It's a non-trivial change.