RPTools / maptool

Virtual Tabletop for playing roleplaying games with remote players or face to face.
http://rptools.net
GNU Affero General Public License v3.0
784 stars 259 forks source link

[Bug]: JAR build is unable to use GraalJS #4354

Open kwvanderlinde opened 10 months ago

kwvanderlinde commented 10 months ago

Describe the Bug

When running MapTool directly from the released JAR file, the js.createNS() function fails with this message:

Event continuing after error running onCampaignLoad@Lib:Elf: java.lang.IllegalArgumentException: Could not find option with name js.ecmascript-version. error executing expression js.evalURI("elf", "lib://Elf/macro/udf.js", "Example").

To Reproduce

  1. Open this campaign file: 4354-graaljs.cmpgn.renamedto.zip
    • The Lib:Elf token has an onCampaignLoad that sets up the JS namespace and runs it sole function.
  2. Observe the stated error message.

Expected Behaviour

For the attached campaign, the message "Test hi" should be printed to chat.

In general, it should be possible to use GraalJS (js.* functions) even when running via the JAR release.

Screenshots

No response

MapTool Info

1.13.2

Desktop

Linux Mint 21.2

Additional Context

No response

kwvanderlinde commented 10 months ago

I've done a bit of sleuthing on this already. The only way this error made sense to me is that GraalJS was somehow not being registered. Some debugging showed that to be correct, instead there was only the "regex" language available but no "js" language.

I found this GraalJS issue which is also using an uber JAR setup, but with exactly the opposite problem ("js" is available, "regex" is not). In summary, files from different dependencies can overwrite / hide each other when creating an uber JAR, in this case preventing one language from being registered with Graal. On another note, I've noticed before that 1.13.2 can't be extract via unzip due to the presence of conflicting files; instead I have to use jar xf ..., and this should have been a red flag to me a long time ago...

The comments at the end of that issue suggest this can be solved by using the mergeServiceFiles() option for shadowJar. We don't use shadowJar, but I took it for spin anyways on the 1.13.2 tag. And it absolutely worked! Js functions worked perfectly and my unzip issue also disappeared :smirk:.

I haven't done much testing beyond that, so I don't know if there are downsides. But at least it looks like there is an avenue to fixing this.


To really sum up, our JAR's /META-INF/services/com.oracle.truffle.api.TruffleLanguage$Provider file contains:

com.oracle.truffle.regex.RegexLanguageProvider

We want it to contain (as my shadowJar version does):

com.oracle.truffle.js.lang.JavaScriptLanguageProvider
com.oracle.truffle.regex.RegexLanguageProvider