How to set Java Function interface with JavetCallBackContext
Hi,
I am migrating from Nashhorn to Javet and I found a bit of issue when setting Java object which is implementing the Function Interface.
By default Nashhorn calls the apply method but in order to use JavetCallBackContext how I can set that to the v8 Global object. Your suggestion would be appreciated.
Thanks
public class Main {
// a Function implementation
private static class MyFunc implements Function<String, Void> {
@Override
public Void apply(String msg) {
System.out.println(msg);
return null;
}
}
public static void main(String[] args) throws Exception {
ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine e = m.getEngineByName("nashorn");
// expose functional interface object as a global var
e.put("dump", new MyFunc());
// invoke functional interface object like a function!
e.eval("dump('hello')");
}
}
Please check this doc out.
Thanks for quick response. Well this doc says where we are creating a new customized callback receiver, but unfortunately in my requirement the jars are externally maintained and we just use them like as it is .In the example I have given above can we use as like below or is there any workaround?
Object.setFunction("dump", MyfunObj::apply)
A small code snippet will be much helpful for the above example
Please follow the doc and use MyfunObj.class.getMethod("apply") instead.
Thanks a lot for the reply. Your suggestion worked like a charm. However I am facing an issue when that apply method is returning any pojo the V8CallBackFuntion is basically converting the returning object into V8Value and inside that conversion method which is PrimitiveConverter making it undefined as the returning object is not of any of primitive type like String or Long etc.
Is there a way we can assign the returning object as it is to the JavaScript variable.
E.g
var x = demo(arg1,arg2); -> demo is returning a Employee object contains name, age, dept. var y = x.employee.name ; x-> is undefined here
I have followed the doc and test cases you have provided in GitHub but I didn’t find any solution.
Please check this tutorial out.
Thanks again for the help. With proxy converter it worked fine. But there is another issue which I am facing now is the auto conversion of the method parameter. If we pass any object into JavaScript function but that method signature is having string as parameter in Java our binding is not converting it obj.toString(). Hence I am getting casting error where the bind (Java) method is expecting a String as parameter and inside JavaScript we are passing an object to that method.
Can you please suggest how can we handle this. This is working fine in Nashhorn
Further more how can I attach overloaded methods of Java to the global object. If I pass the same name will it not overwrite the method signature ?
- Implement your own converter which inherits the proxy converter. You may do whatever you want to do.
- The easiest way is to write a dispatching JS function.
globalThis.a = () => {
if (arguments.length == 1) {
a1(...arguments);
}
if (arguments.length == 2) {
a2(...arguments);
}
// ...
}