Reputation: 1063
I am migrating a project from Nashorn to graal.js. The project utilizes a large amount of scripts (over 3,400) and there's a function on the Java side which invokes a method; the method returns a JavaScript list of objects.
function filterList(ob)
{
var list = [];
var arr = ob.toArray();
for(var i = 0; i < arr.length; i++)
{
if(global.isValid(arr[i]))
{
list.push(arr[i]);
}
}
return list;
}
This worked fine on Nashorn previously with the use of ScriptUtils. This code was written by the developer who worked on the project before I picked it up:
try {
Object p = iv.invokeFunction("filterList", this.getList());
if(p != null) {
List<MyObj> lObj = new ArrayList<>(((Map<String, MyObj>)(ScriptUtils.convert(p, Map.class))).values());
return lObj;
}
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
How can I access the array through Java with graal.js? I have tried using Value.asValue(p)as(MyObj[])
to no avail. I have also tried following the Nashorn migration guide where they suggest to cast the object to List or Map, to no avail either.
I'm aware of a solution where I would have to rewrite the script to just use new Java.type('java.util.ArrayList');
and return a List
rather than an array - however there are thousands of scripts and rewriting all of them will be incredibly tedious.
Upvotes: 0
Views: 2144
Reputation: 296
you can use Value.getArraySize() and Value.getArrayElement(index):
Context context = Context.newBuilder("js").build();
Value result = context.eval("js", "var list=[1,2,'foo',true]; list;");
if (result.hasArrayElements()) {
for (int i=0;i<result.getArraySize();i++) {
System.out.println(result.getArrayElement(i));
}
}
You find the full JavaDoc of the Value class in https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Value.html
Best, Christian
Upvotes: 1