He estado usando GraalVM para ejecutar Javascript desde java. Pero tengo un problema: no sé cómo obtener campos o invocar métodos de un objeto js desde java. Este es mi código, java:
public static class JavaMethods { public void printWidthOf(Object size) { System.out.println("printWidthOf started"); System.out.println("size class is " + size.getClass().getName()); // prints PolyglotMap Map map = (Map) size; // PolyglotMap implements Map so i tried that System.out.println("size width is " + map.get("size")); // doesn't work, prints null instaed of 40 } } public static void main(String[] args) throws Exception { GraalJSEngineFactory factory = new GraalJSEngineFactory(); GraalJSScriptEngine engine = factory.getScriptEngine(); Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE); bindings.put("polyglot.js.allowHostAccess", true); bindings.put("JavaMethods", new JavaMethods()); engine.eval(new FileReader("MyScript.js")); engine.invokeFunction("start"); }JavaScript:
class Size { #width; #height; constructor(w, h) { this.#width = w; this.#height = h; } getWidth() { return this.#width; } getHeight() { return this.#height; } } function start() { var mySize = new Size(40, 60); JavaMethods.printWidthOf(mySize); }Producción:
printWidthOf started size class is com.oracle.truffle.polyglot.PolyglotMap size width is nullEntonces, ¿cómo puedo obtener un campo de PolyglotMap (objeto js) de Java?
Encontré la solución.
public static class JavaMethods { public void printWidthOf(Object size) throws Exception { Field f = size.getClass().getDeclaredField("guestObject"); f.setAccessible(true); JSOrdinaryObject obj = (JSOrdinaryObject) f.get(size); System.out.println(obj.getValue("width")); } }