JDK-8068603 : NashornScriptEngine.put/get() impls don't conform to NPE, IAE spec assertions
  • Type: Bug
  • Component: core-libs
  • Sub-Component: jdk.nashorn
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2015-01-07
  • Updated: 2015-09-29
  • Resolved: 2015-01-20
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 b48Fixed
Description
The spec for the methods
http://docs.oracle.com/javase/8/docs/api/javax/script/ScriptEngine.html#put-java.lang.String-java.lang.Object-
http://docs.oracle.com/javase/8/docs/api/javax/script/ScriptEngine.html#get-java.lang.String-

says: 
"Throws:
NullPointerException - if key is null.
IllegalArgumentException - if key is empty." 

However the following code executed on Oracle's JDK. 

        new ScriptEngineManager().getEngineFactories()
                .stream()
                .map(ScriptEngineFactory::getScriptEngine)
                .forEach(e -> {
                    e.get("");
                    e.get(null);
                    e.put("", "a");
                    e.put(null, "a");
                });

results in no exceptions thrown which doesn't conform to the current spec and the corresponding JCK9(b05) tests will fail on JDK9: 

api/javax_script/ScriptEngineFactory/index.html#GetParameter[get_keyIsEmpty_IAE] 
api/javax_script/ScriptEngineFactory/index.html#GetParameter[get_keyIsNull_NPE] 
api/javax_script/ScriptEngineFactory/index.html#GetParameter[put_keyIsEmpty_IAE] 
api/javax_script/ScriptEngineFactory/index.html#GetParameter[put_keyIsNull_NPE] 


Comments
This is because our ENGINE_SCOPE object is a ScriptObjectMirror, and those allow both null and empty string keys. To wit, ScriptObjectMirror implements Bindings, which should also prohibit non-String keys, as well as null keys and empty string, but we currently allow them. The reason we allow these is that mirrors are also used for wrapping JS objects passed across Global boundaries, and in JS both null and empty string keys are allowed. The below program prints what is intuitively correct ("null-value" then "empty-value"): ScriptEngine e = new NashornScriptEngineFactory().getScriptEngine(); e.put(null, "null-value"); e.put("", "empty-value"); e.eval("(function() { print(this[null]); print(this['']); })();"); Yet it should be prohibited by the Scripting API. We can override NashornScriptEngine.get and put to explicitly disallow these keys while allowing them in ScriptObjectMirror. (We will still be violating the Bindings contract in ScriptObjectMirror for a bunch of its methods then.)
20-01-2015