Functionality of JSScripting vs. node.js

Hi,

this week I started playing around with the powerful JSscripting 3.2 engine, but ran into a few issues using npm modules.

I tried using a script that runs fine with nodejs and makes use of libraries like Jimp, gifwrap and ws (WebSockets).

However, after installing the libraries in the node_modules directory, I soon ran into two types of problems:

  • GraalVM seems to love all js files below this directory - including those integrated into the libraries for testing purposes etc.
[ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/etc/openhab/automation/js/node_modules/process/test.js': org.graalvm.polyglot.PolyglotException: TypeError: Cannot load CommonJS module: 'assert'
[ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/etc/openhab/automation/js/node_modules/xml2js/lib/builder.js': org.graalvm.polyglot.PolyglotException: TypeError: Cannot load CommonJS module: './defaults'
[ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/etc/openhab/automation/js/node_modules/xtend/test.js': org.graalvm.polyglot.PolyglotException: TypeError: Cannot load CommonJS module: 'tape'

=> Do I understand correctly that this behavior is part of [jsscripting] JS script engine no longer watches node_modules for scripts by jpg0 · Pull Request #11830 · openhab/openhab-addons · GitHub and should be fixed when I install a nightly build?

  • GraalVM does not provide all built-in functionality that is included with nodejs.
[ERROR] [b.automation.script.javascript.stack] - Failed to execute script: org.graalvm.polyglot.PolyglotException: TypeError: Cannot load CommonJS module: 'assert'
[ERROR] [b.automation.script.javascript.stack] - Failed to execute script: org.graalvm.polyglot.PolyglotException: TypeError: (intermediate value).nextTick is not a function
[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'ede0555c07' failed: org.graalvm.polyglot.PolyglotException: TypeError: Cannot load CommonJS module: 'events'
[ERROR] [b.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: TypeError: Cannot load CommonJS module: 'https'

Is there anything I can do to get this functionality?

Not tested yet, but I for sure know that some of the libs I use make extended use of Promises. Will these work, or will this become the next issue, given that GraalVM is single-threaded?

@rlkoshak Thanks for your great work and tutorials!

My understanding is to get full node support one has to run an instance of Node.js along side of openHAB and start up GraalVM with a different set of flags. That’s not really something we know how to package up and distribute as part of OH and I know of no one who has successfully done it yet. You can find details at GraalVM.

I can’t answer the first question.

Not at this time and I don’t know if ever. See GraalVM. In particular:

  1. An arbitrary number of JavaScript Contexts can be created, but they should be used by one thread at a time.
  2. Concurrent access to JavaScript objects is not allowed: any JavaScript object cannot be accessed by more than one thread at a time.
  3. Concurrent access to Java objects is allowed: any Java object can be accessed by any Java or JavaScript thread, concurrently.

Because of the way that rules are run, attempting to do anything with threads results in a “single threaded only” exception because it causes concurrent access to JS objects (namely the script). And there is no internal loop driving things like in Node so if you set a promise the script just exits. There is nothing waking it up to see if the promise has been met.

All of these issues are known and being explored but there is no timeline for when/if they can be addressed.

1 Like

Hi Rich,

thanks for your valuable input. I decided to use node.js separately from OpenHAB, additionally run node-RED and have those two communicate via Items. By this, functionality that requires libraries can be placed in and administered by Node-RED, and everything that belongs to OpenHAB will happen in OpenHAB.

Thanks again! The new JS engine makes OH much more powerful!