I am working with the org.graalvm.polyglot
script engine in my Java11 project to evaluate a JavaScript.
The script to be evaluated returns a JavaScript array with two entries.
...
var result={};
result.isValid=false;
result.errorMessage = new Array();
result.errorMessage[0]='Somehing go wrong!';
result.errorMessage[1]='Somehingelse go wrong!';
....
In my java code I try to evaluate the result object:
Value resultValue = context.getBindings(languageId).getMember("result");
In my Eclipse Debugger I can see that I receive a PolyglotMap containing the expected values:
I can iterate over that map to get the values with a code like this:
...
try {
mapResult = resultValue.as(Map.class);
} catch (ClassCastException | IllegalStateException | PolyglotException e) {
logger.warning("Unable to convert result object");
return null;
}
Iterator it = mapResult.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
String itemName = pair.getKey().toString();
Object itemObject = pair.getValue();
...
In this way I am able to extract the boolean 'isValid'. But with the object 'errorMessage' I struggle.
Inspecting the Object again within the Eclipse Debugger it looks like this:
If I test this object it is an instanceOf Map. But I am unable to get any of the values out of this object.
Can anybody help me to understand what exactly this object represents and how I can extract the both values 'Someting go wrong!'
and 'Sometingelse go wrong!'
?
When I iterate over this second map it seems to be empty - even if the debugger shows me the correct values.
I'm not 100% sure why as(Map.class)
behaves that way, it might be worth creating an issue on github to figure it out: github.com/oracle/graal
But if you access the values using the API without converting to a Map it would work as you expect:
var errorMessage = resultValue.getMember("errorMessage");
errorMessage.hasArrayElements(); // true
var _0th = errorMessage.getArrayElement(0);
var _1th = errorMessage.getArrayElement(1);
You can also convert the polyglotMap to Value and then do it:
val errorMessage = context.asValue(itemObject);
errorMessage.hasArrayElements(); // true
errorMessage.getArrayElement(0);
PolyglotMap of course has the get
method. And the Value javadoc says that:
Map.class is supported if the value has Value.hasHashEntries() hash entries}, members or array elements. The returned map can be safely cast to Map. For value with members the key type is String. For value with array elements the key type is Long.
Can you try getting them with the Long keys? There might be something obvious I'm missing, so in any case it's better to raise an issue on GitHub.