Nashorn: evaluating JavaScript expression throws cast class exception for function open using lambda

I have the following class with one variable of type Long

package com.nm.poc; public class JSLong{ private Long longValue; public Long getLongValue() { return longValue; } public void setLongValue(Long longValue) { this.longValue = longValue; } public Long testLongValue(Long longValue){ return longValue; } } 

I call testLongValue method from JavaScript as follows

 package com.nm.poc; import java.util.function.Consumer; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; public class Main { public static void main(String[] args) throws Exception { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("nashorn"); JSLong jsLong = new JSLong(); //WORKS engine.put("jsLong", jsLong); engine.eval("print(jsLong.testLongValue(20))"); //Throws ClassCast Integer to Long engine.put("jsLong2", (Consumer<Long>)jsLong::testLongValue); engine.eval("print(jsLong2(20))"); } } 

engine.eval("print(jsLong.testLongValue(20))"); works

engine.eval("print(jsLong2(20))"); exclude cast cast class

Can I do the engine.eval("print(jsLong2(20))"); for long type

Exceptional Trace

 Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long at jdk.nashorn.internal.scripts.Script$1$\^eval\_.:program(<eval>:1) 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(Unknown Source) at com.nm.poc.Main.main(Main.java:20) 
+5
source share
1 answer

First of all: Consumer represents a method / function that returns no value. To print the return value, you must use a function.

In either case, using the function will throw the same exception.

 //Throws ClassCast Integer to Long engine.put("jsLong2", (Function<Long, Long>)jsLong::testLongValue); engine.eval("print(jsLong2(20))"); 

There must be an explicit casting somewhere in the Nashorn code that works for int / long, but obviously does not work for Integer / Long.

To make your work example you can use LongUnaryOperator .

 //This works engine.put("jsLong2", (LongUnaryOperator)jsLong::testLongValue); engine.eval("print(jsLong.testLongValue(20))"); 

LongUnaryOperator uses a raw long type instead of a long class, so that it can be distinguished to / from the whole.

You should know that there is no 64-bit integer in JS, so passing long to js via Nashorn may cause some of them:

Javascript long integer

Java 8 / Javascript (Nashorn) long interoperability

0
source

Source: https://habr.com/ru/post/1269497/


All Articles