Graal (ECMA 2021, V11) vs. Nashorn (V5.1): Converting Java Set to JavaScript Array throws exception

Hi,

I am convierting my Nashorn rules to Graal rules (ECMA2021). Until now I could use this code:

var gHouse = ir.getItem('gModelLocationHouse').members;
var allItems = Java.from(gHouse);  

The var “allItems” was an JS array then.

I transformed it to:

var gHouse = runtime.itemRegistry.getItem('gModelLocationHouse').members;
var allItems = Java.from(gHouse);

In ECMA2021 I now get this error:

2023-02-26 10:46:23.724 [ERROR] [b.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: TypeError: Cannot convert to JavaScript array.
	at <js>.:program(<eval>:596) ~[?:?]
	at org.graalvm.polyglot.Context.eval(Context.java:379) ~[?:?]
	at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:458) ~[?:?]
	at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:426) ~[?:?]
	at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) ~[java.scripting:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:51) ~[?:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.eval(InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.java:69) ~[?:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:51) ~[?:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.eval(InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.java:69) ~[?:?]
	at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.lambda$0(ScriptActionHandler.java:58) ~[?:?]
	at java.util.Optional.ifPresent(Optional.java:183) [?:?]
	at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.execute(ScriptActionHandler.java:55) [bundleFile:?]
	at org.openhab.core.automation.internal.RuleEngineImpl.executeActions(RuleEngineImpl.java:1181) [bundleFile:?]
	at org.openhab.core.automation.internal.RuleEngineImpl.runRule(RuleEngineImpl.java:989) [bundleFile:?]
	at org.openhab.core.automation.internal.TriggerHandlerCallbackImpl$TriggerData.run(TriggerHandlerCallbackImpl.java:89) [bundleFile:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
	at java.lang.Thread.run(Thread.java:829) [?:?]
2023-02-26 10:46:23.735 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID '272569f77a' failed: org.graalvm.polyglot.PolyglotException: TypeError: Cannot convert to JavaScript array.

Which code I can use to convert an Java array to JavaScript array in ECMA2021?

Thanks in advance!
HFM

GraalVM is much more strict when converting data types.
The members property of the is of type Java Set, no Array.
Therefore it is failing.

You can convert a Java Set to a JS Array:

const ArrayList = Java.type('java.util.ArrayList');

const set;
const jsArr = Java.from(new ArrayList(set));

However it is HIGHLY recommended to not work with the raw Java APIs and instead make use of the included openhab-js library, which provides a high-level JS API to work with openHAB, see JavaScript Scripting - Automation | openHAB.

Using this, your code would look like the following:

var allItems = items.getItems();
var groupMembers = items.getItem(„gModelLocationHouse“).members;

(Sorry for the wrong „“ signs, blame my iPad.)

Both are a native JS array of JS Items, no more messing with Java data types.

1 Like

Please don‘t forget to mark this as solved if I solved your problem :wink:

Hi Florian,

I try to update to 3.4.2 today and to adapt your suggestions. If everything is fine I will check the topic as solved.

Nevertheless, thank you for your fast answer!
HFM

1 Like

I’ll only add that the openhab-js library is very well documented in the add-on’s readme. It should always be the first place to look to find out how to do something in JS Scripting. I can’t tell you how many times I’ve answered questions from people guessing at the syntax when the real way is clearly covered in the docs.

I’m not saying this is one of those times. I just want to help you avoid done frustration going forward. The openhab-js library does a lot differently from the other languages.

2 Likes

Thanks for your hints, Rich, as always very appreciated!

Before I ask a question I mostly invested a few hours to find a solution myself. Then I am often desperated. :slight_smile:

HFM

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.