FULL PRODUCT VERSION :
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux XXX 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u3 (2016-01-17) x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
When an AbstractJSObject claims to be a function (isFunction()), and is put in the context with put(String, Object), you cannot call apply on it.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
public void nashornApply() throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
engine.put("f", new AbstractJSObject() {
@Override
public boolean isFunction() {
return true;
}
@Override
public Object call(Object thiz, Object... args) {
System.out.println("thiz = " + thiz);
System.out.println("args = " + Arrays.toString(args));
return null;
}
});
engine.eval("f(1,2,3);");
engine.eval("f.apply(null, [1,2,3]);");
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
thiz = undefined
args = [1, 2, 3]
thiz = undefined
args = [1, 2, 3]
ACTUAL -
thiz = undefined
args = [1, 2, 3]
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.445 sec <<< FAILURE!
nashornApply(dk.kosmisk.jslib.NashornApplyTest) Time elapsed: 0.409 sec <<< ERROR!
javax.script.ScriptException: TypeError: null is not a function in <eval> at line number 1
at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:467)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:451)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:403)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:399)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
...
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" javax.script.ScriptException: TypeError: null is not a function in <eval> at line number 1
at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:467)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:451)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:403)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:399)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
at Main.main(Main.java:46)
Caused by: <eval>:1 TypeError: null is not a function
at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:213)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:185)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:172)
at jdk.nashorn.internal.runtime.linker.NashornBottomLinker.linkNull(NashornBottomLinker.java:172)
at jdk.nashorn.internal.runtime.linker.NashornBottomLinker.getGuardedInvocation(NashornBottomLinker.java:64)
at jdk.internal.dynalink.support.CompositeGuardingDynamicLinker.getGuardedInvocation(CompositeGuardingDynamicLinker.java:124)
at jdk.internal.dynalink.support.LinkerServicesImpl.getGuardedInvocation(LinkerServicesImpl.java:154)
at jdk.internal.dynalink.DynamicLinker.relink(DynamicLinker.java:253)
at jdk.nashorn.internal.scripts.Script$1$\^eval\_.:program(<eval>:1)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:640)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:228)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:446)
... 5 more
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class Main {
public static void main(String[] args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
engine.put("f", new AbstractJSObject() {
@Override
public boolean isFunction() {
return true;
}
@Override
public Object call(Object thiz, Object... args) {
System.out.println("thiz = " + thiz);
System.out.println("args = " + Arrays.toString(args));
return null;
}
});
engine.eval("f(1,2,3);");
engine.eval("f.apply(null, [1,2,3]);");
}
}
---------- END SOURCE ----------