JDK-8066773 : JSON-friendly wrapper for objects
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: jdk.nashorn
  • Affected Version: 9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2014-12-05
  • Updated: 2017-05-17
  • Resolved: 2015-06-02
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.
JDK 8 JDK 9
8u60Fixed 9 b68Fixed
Description
There's a need for a ScriptObjectMirror-equivalent for Arrays that implements List<Object> instead of Map<String, Object>.

As discussed in this thread: http://mail.openjdk.java.net/pipermail/nashorn-dev/2014-November/003911.html

Design constraints:

- A single class can't implement both List and Map in Java. (Incompatible signature of remove() method & incompatible implementation requirements on hashCode()).

- We can't stop wrapping all objects in ScriptObjectMirror, as ScriptObjectMirror is a public class, and we allowed people to expect it. If we now started returning ScriptObjectMirror sometimes and ArrayMirror (provisional name) other times, that'd be an API breaking change. That's sad, really ��� we should've probably never made ScriptObjectMirror public and instead forced people to only program against the JSObject interface instead, but that horse has left the barn now.

Solution:

- We can still create a separate "class ArrayMirror implements JSObject, List<Object>" for wrapping JS Arrays, but one will need to explicitly ask a mirror that'll return these transitively, e.g. we could give people a Java.toJSONCompatible(obj) API that one would use as: "myObject.expectsJSON(Java.toJSONCompatible(someJson));" It'd still be returning a ScriptObjectMirror on the top level (as long as it ain't an array in which case the top level would itself be an ArrayMirror), but it'd be carrying a hidden flag that'd change its behavior so whenever code retrieves an Array from it, it gets wrapped into ArrayMirror and not ScriptObjectMirror. Also, if Object is retrieved from it, it'd return a ScriptObjectMirror with this flag propagated, so Arrays at any nesting depth would always be exposed as Lists. Arguably, this could be the default behaviour except for the fact that it isn't how it worked since the initial 8 release and we can't break backwards compatibility���

The existing ListAdapter can probably be reused as "ArrayMirror".