graaljs: Cannot assign object data in Java script code. TypeError: writeArrayElement on foreign object failed due to: Message not supported.
Hello
In GraalVM CE 19.2.0, I have jsonObject build in Java using ProxyObject and passed to GraalVM Context. Then I want to update in Java script guest code and got an exception.
...
//Java on host
try (Context jsContext =
Context.newBuilder("js").allowHostAccess(HostAccess.EXPLICIT).build()) {
jsContext.getBindings("js").putMember("jsonObject", initDataProxy);
jsContext.eval("js", jsCode);
}
}
...
//Java script on guest
for (var key in jsonObject) {
jsonObject[key] = {'a':'b'};
}
...
Here exception message:
Exception in thread "main" TypeError: writeArrayElement on foreign object failed due to: Message not supported.
at <js> :program(Unnamed:1:1557-1583)
at org.graalvm.polyglot.Context.eval(Context.java:370)
at com.researchforgood.survey.surveyengine.service.JSProxyBuilderTest.performanceTest(JSProxyBuilderTest.java:174)
at com.researchforgood.survey.surveyengine.service.JSProxyBuilderTest.main(JSProxyBuilderTest.java:265)
As you see I cannot assign object data in JS code. Am I doing something wrong and this is documented somehow? How can I assign data?
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 17 (5 by maintainers)
Commits related to this issue
- #206 - allow ProxyObject to accept numeric String keys — committed to acadiamjh/graaljs by acadiamjh 5 years ago
Hi @pavlomorozov
I can reproduce your problem. We are investigating.
Best, Christian
The root of the problem is that JavaScript (unlike the interop API) does not distinguish numeric and string properties.
object[42]andobject['42']are the same in JavaScript but there are two methods in the interop API (writeMember()andwriteArrayElement()) that can be mapped to this JavaScript operation.Our current rule/heuristics (described by @woess above): “if the key is a string, we send
writeMember()and if it’s a number, we sendwriteArrayElement()” does not work well when thekeyis (or can be converted to) a number but the corresponding object does not have array elements (like a typicalProxyObject). I think that we should modify this rule such thatwriteArrayElement()is called on an object that actuallyhasArrayElements()only. Otherwise thekeyshould be converted to string andwriteMember()should be used instead. This change would ensure thatproxyArray[42]would triggerwriteArrayElement()still but bothproxyObject[42]andproxyObject['42']would work as expected.