GraalVM for automation

Tags: #<Tag:0x00007f7458df46d8>

GraalVM:

  • Provides a jsr223 implementation
  • Is replacing Nashorn
  • Allows running in a ‘Nashorn-compatible’ mode to support it’s extensions
  • Supports significantly more JS than Nashorn (ES6 for example)
  • Runs on JDK8

Has anyone looked at switching out the current Nashorn implementation with Graal? Is there any reason that this shouldn’t be attempted? I was considering giving it a go to get ES6, but wanted to check if there has been anything done before in this area.

Thanks

We had this topic already but I don’t know the current state.

See:

and

For example.
But there are more search results for graal vm available.

I’m not aware of anyone working on it. I did look at it back in January (2019) and saw it was still in beta and I thought I remember it only worked for newer Java versions. But that doesn’t seem true. I don’t know what the precise state is, but I think it’s a very good idea to work on it!

My understanding was GraalVM was always the plan. The assumption was that we needed to move past Java 8 to use it. If that’s not the case, please please please take a crack at it. :slight_smile: I know before you came along Scott was waiting until we could move to GraalVM so we can take advantage of newer JS capabilities before working heavily on the JS Helper Libraries.

Not only should this be attempted, it is very much desired.

1 Like

According to the GraalVM website the current version is based von Java 8. Currently it is not available for ARM platforms like Raspberry.

I have looked into this and hope to implement (or help to implement :wink:) GraalVm, but this would not be allowed before OH3, since it would require gutting scripted automation. There are also a LOT of things that I (hopefully, everyone!) would like to see implemented before then! OH3 will also allow for JDK9(or 11), which will give us ES6, so a lot of new stuff to play with and slightly lessens the benefit of GraalVM.

IMO, GraalVM will fit in further down the road… probably way down the road. The new rule engine and scripted automation should be officially released (OH3) before they get completely reworked! If you want to dig into it, start getting familiar with everything under org.openhab.core.automation!

@MHerbst do you know exactly which parts are not available? I ask because we would only need the scripting engine part, which (afaics) doesn’t require the complete VM or the aot compiler.

@5iver why do you say that it would require gutting the existing code? I was assuming that it could just be plugged in as an additional standard javax.scripting engine. I know it’s recommended to use it directly (for greater configuration ease and faster runtime), but I would expect that we’d still get most of the benefit if we used it as a script engine. (oh, and yes I’ve already been getting familiar with that bundle!)

No, I just had a look at the GraalVM website. I did not had enough time to test GraalVM

An update: I have GraalVM now working for scripted automation; I’ve put everything in a separate plugin and ensured that it’s isolated to scripted automation (e.g. transformers still use Nashorn). There are NO changes to the existing scripted automation pieces - just Graal registered as a new scripting engine which takes priority over Nashorn. I have a fairly extensive set of JS for automation and I’ve ensured that everything works under Graal.

I’ve discovered:

  • Graal does indeed work on arm (I’m testing on an rpi4), with JDK8 (although there is no AOT compilation in this mode, which imo is fine).
  • I’ve tested some bits of ES6 which are working fine
  • The majority of the code in openhab-scripters works fine on Graal (but there are a few minor pieces to fix)
  • Graal is certainly NOT written to directly work in OSGi; although with some minor handling (after major investigations!) I’ve got it working and contained to a single bundle
  • Moving off Nashorn to Graal as a general rule should actually allow removing some of this handling (and OSGi-ising the Graal libs themselves).

I have currently done this as an add-on in openhab-addons, although obviously it should move to core at some point if it’s to replace Nashorn.

I will submit a PR, although I want to port all my existing code from CommonJS modules to ES6 modules to ensure this works before I do.

2 Likes

When your last post came up, I realized I had never posted my reply!

That’s what I was thinking of.

Even if you go the javax.script route, it would require some effort to get the ScriptEngineFactories setup and differentiating between the Nashorn script engine in the JDK and the one from GraalVM. Also, there appears to only be a JavaScript ScriptEngine provided… there does not look to be a GraalVM ScriptEngine for Python.

There are no priorities in the loading of script engines, so you must be getting lucky and Nashorn is loading first and is then overwritten when graaljs loads. It would be nice to see some logs from startup. As I mentioned above, to do it right, a ScriptEngineFactory should be setup for graaljs or the NashornScriptEngineFactory should be modified to differentiate between the two. I didn’t plan on this work until Nashorn was removed from the jdk and there was a replacement JS script engine.

Do you mean you are loading graaljs as an OSGi bundle? How did you get the script engine into the classpath so that automation would load it? I am very curious to see what you’ve got, as I’ve done a bit of work on setting up Jython and Groovy script engine addons but shelved them after frustration with the IDE after the move to bnd. Script engine addons also seemed a dead end and it looked to me as though script engines would need to be added through configuration options in the rule engine. I’ll be digging this work back up once the snow sets in. There are a lot of script engines that work with OH, we just don’t have an easy way to install them yet.

I haven’t tried it with graaljs, but you should be able to just add the jar to /runtime/bin/ext/ or add it to the bootclasspath (as instructed in the helper library documentation).

Script engines have not been included in OHC, or Jython would have been included a LONG time ago! Before submitting the PR, I suggest opening an issue to ask the maintainers where the best place would be for a script engine addon. IMO, it would be best to separate automation from OHC and use a new repo for rule engines, script engines, module types, rule templates, etc. As I’ve mentioned, I plan to bring this up when we get closer to OH3.

you must be getting lucky and Nashorn is loading first and is then overwritten when graaljs loads

No, the ScriptEngineFactory already differentiates between ‘generic’ (e.g. registered in javax.script) and ‘custom’, and gives priority to custom. I do not have GraalJS register itself with javax.script, so it’s custom, which gets priority over Nashorn, which is generic.

Do you mean you are loading graaljs as an OSGi bundle?

Yes, although not standalone - as an included dependency of my bundle.

How did you get the script engine into the classpath so that automation would load it?

I didn’t, it’s part of my bundle. I just provide my own ScriptEngineFactory which gets injected into the ScriptEngineManagerImpl.

I haven’t tried it with graaljs, but you should be able to just add the jar to /runtime/bin/ext/ or add it to the bootclasspath (as instructed in the helper library documentation).

The problem with giving GraalJS free reign is that it completely trashes Nashorn (by using reflection to set a load of it’s fields to null). This breaks other areas, such as Nashorn’s existing registration as an engine in OH, as well as the JS Transformation service (I’ve currently left this as Nashorn, but it’s straightforward to move it too). I have code to prevent it from doing this by preventing it seeing Nashorn, and I can control whether it’s registered in javax.script too (as this is bundles-specific). Not being registered makes no difference to it’s operation.

Anyway, if you want to check it out, it’s on a branch here: https://github.com/jpg0/openhab2-addons/commits/add-graaljs

Thanks for the advice regarding where to put it; I’ll open an issue.

ps. It’s also looking unlikely that I’ll be able to get ES6 module support in :frowning: GraalJS only supports it as experimental for it’s nodejs runtime, and not at all for embedded scripts. At least that’s what I can see and have not even been able to get it to recognise the ESM syntax yet. If I can’t get it to work I will probably fall back to CommonJS style, just pull the loading mechanisms up into the Java code.

1 Like

I have opened an issue here: https://github.com/openhab/openhab-core/issues/1177

Regarding module support, I have not managed to get ES6 modules to work, but do have fully nodeJS compliant CommonJS support moved into the Java code.