Using GraalVM, to expose Java objects to JavaScript, I am using ProxyObject
to wrap them. For this purpose, I am using ProxyObject.fromMap
method like the following:
ProxyObject exposedObject = ProxyObject.fromMap(objectMapper.convertValue(javaObject, Map.class));
Here, the javaObject
is of Object
class and can be arbitrarily complex. This method works for immediate members of javaObject
, but not when the members are complex objects themselves. For example, if one of the members of javaObject
happens to be a Map
, like:
final Map<String, Object> source = new HashMap<>();
source.put("id", "1234567890");
final Map<String, Object> sourceComponent = ImmutableMap.of("key", "value");
source.put("complex", sourceComponent);
// assuming the source is any object
ProxyObject exposedObject = ProxyObject.fromMap(objectMapper.convertValue(source, Map.class));
// or knowing that source is in fact a map
ProxyObject exposedObject = ProxyObject.fromMap(source);
this is what happens when the exposedObject
is accessed in JavaScript:
exposedObject; // returns {complex: JavaObject[com.google.common.collect.SingletonImmutableBiMap], id: "1234567890"}
exposedObject.id; // returns 01234567890
exposedObject.complex; // returns {key=value}
exposedObject.complex.key; // returns undefined
So my question is how we can fully expose an arbitrarily complex and deep java object to javascript. Do we have to go through all members recursively and wrap them into ProxyObject
s? Or is there a supported out-of-the-box method of achieving this?
Also, please let me know if my approach needs to change.
As the javadoc for ProxyObject [1] says "Interface to be implemented to mimic guest language objects that contain members.". This means that if you want the Java object to be used in JavaScript as if it was native to JavaScript it needs to be a ProxyObject.
On the other hand, as the website docs [2] show, Java objects passed into JavaScript can still be used as Java objects (i.e. they don't mimic JS objects by default). This means you can access fields, invoke methods, etc. The website docs show an example:
[1] https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/proxy/ProxyObject.html
[2] https://www.graalvm.org/reference-manual/embed-languages/