What data type will the javascript function like
(event) => {
event.preventDefault();
host.somethingsomething();
}
be cast to in Java?
I have Java host objects for event and for host.
I don't know how to turn the JavaScript anonymous function into a function I can run in Java.
Hi @theonlygusti
it should work to accept a value of org.graalvm.polyglot.Value type. You can use canExecute() and execute(arg...) on that:
test.js:
var obj={myFn: function() { print("myFn called"); } };
var host={something: function() { print("something called"); } };
var arrowFn = (event) => { event.myFn(); host.something(); return "arrow finished"; }
var anonFn = function(arg) { print("anonymous function, arg:"+arg); return "anonymous finished"; };
var GH112 = Java.type("GH112");
GH112.run(anonFn, obj);
GH112.run(arrowFn, obj);
GH112.java:
import org.graalvm.polyglot.Value;
public class GH112 {
public static void run(Value obj, Value arg) {
System.out.println("[JAVA] canExecute: "+obj.canExecute());
if (obj.canExecute()) {
System.out.println("[JAVA] result: "+obj.execute(arg));
}
}
}
Best,
Christian
@wirthi thank you very much, that solves my issue. I feel kind of embarrassed for not doing that already, I've even seen Value used in examples for this exact purpose.
Do you know how I can control the top-level objects that JavaScript has access to? I don't want user-submitted code to be able to use Java or Polyglot.
Hi,
we provide some options to NOT have those elements in the global scope (see https://github.com/graalvm/graaljs/blob/master/docs/user/JavaScriptCompatibility.md). This, however, means that your code does not have access either. If you do need access there, you can enable those elements but delete them once you are done initializing and transfer control to user code. You can still wrap Java, Polyglot, etc. inside your own closures if relevant.
Another strategy is to Polyglot.eval() your user's code. You cannot control what is visible in such contexts, but you could wrap your user's code with some initialization code that deletes the unwanted properties.
The probably cleanest and most flexible solution is to create a new JavaScript org.graalvm.polyglot.Context from Java with the correct options set. Then you'd go your JS app=>your Java wrapper=>user's code. Due to our fast interop, that should not cause any performance problems.
Best,
Christian
@wirthi I got this
Context context = Context.newBuilder("js")
.option("js.graal-builtin", "false")
.option("js.polyglot-builtin", "false")
.option("js.load", "false")
.option("js.print", "false")
.option("js.console", "false")
.build();
but don't see how to disable top-level Java.
Thank you for helping me out so much.
Hi,
deactivating Java should work with adding .allowHostAccess(false) to your list of options.
https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Context.Builder.html
Best,
Christian
Most helpful comment
Hi,
deactivating
Javashould work with adding.allowHostAccess(false)to your list of options.https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Context.Builder.html
Best,
Christian