When I call eval (in strict mode) on a nashorn engine with the following script I get an exception:
var yfunc = function () {
(null).apply(null, arguments);
};
yfunc();
I've truncated my personal situation heavily. The "(null)" on line 2 can be replaced with anything between parenthesis or a local variable, either way just something that shouldn't throw a compile error, and it will yield the same result.
The issue seems to be explicitly that "arguments" is passed directly as the second argument of calling a method called "apply". Any of the following changes will undo the thrown exception:
- Putting "arguments" in a variable first (but simply wrapping it in parenthesis doesn't work!)
- Calling something other than apply
- Passing "arguments" in a different argument slot when calling apply
- Calling print() (with or without passing any arguments) as a preceding line of code inside yfunc() (weird huh?)
- Defining more than 0 parameters for yfunc()
- Binding yfunc first and then calling the bound method
- Calling yfunc via Function.apply (not so much with Function.call!)
The Exception thrown is this:
Exception in thread "main" java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.runtime.Undefined to jdk.nashorn.internal.runtime.ScriptFunction
at java.lang.invoke.MethodHandleImpl.newClassCastException(MethodHandleImpl.java:361)
at java.lang.invoke.MethodHandleImpl.castReference(MethodHandleImpl.java:356)
at jdk.nashorn.internal.scripts.Script$\^eval\_.:program(<eval>:4)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:449)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:406)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
When I call this method with an owner, the exception thrown changes. Example code:
var yfunc = {
method: function () {
(null).apply(null, arguments);
}
};
var x = yfunc.method();
Then the thrown exception looks like this:
Exception in thread "main" java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.scripts.JO4 to jdk.nashorn.internal.runtime.ScriptFunction
at java.lang.invoke.MethodHandleImpl.newClassCastException(MethodHandleImpl.java:361)
at java.lang.invoke.MethodHandleImpl.castReference(MethodHandleImpl.java:356)
at jdk.nashorn.internal.scripts.Script$\^eval\_.:program(<eval>:5)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:449)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:406)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
I've reproduced the issue so far on specifically these environments:
- windows 7 64bit -> jdk 1.8.0_60 64bit
- windows 8 64bit -> jdk 1.8.0_131 64bit
I can't seem to find anything on the internet about similar issues. Do I need to report this to Oracle/OpenJDK?
Minor update
Added items 6 and 7 to list of "following changes will undo the thrown exception".
Final update
Bug filed: JDK-8184720