When calling from JS to Java, Nashorn filters internal implementation objects; ConsString is converted to String and ScriptObject to ScriptObjectMirror before being passed on. Unfortunately, calling a @FunctionalInterface object is implemented as a separate code path, and this filtering is missing there.
import java.util.function.Function;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
public class CS {
public static void main(String[] args) throws ScriptException {
ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine();
engine.put("f", new Function<String, String>() {
@Override
public String apply(String t) {
return t;
}
});
engine.eval("var x = 'a'; x += 'b'; f(x)");
}
}
throws java.lang.ClassCastException: jdk.nashorn.internal.runtime.ConsString cannot be cast to java.lang.String
at CS$1.apply(CS.java:1)
at ...
it should not throw an exception instead.