Description
We have a Java application running on an embedded Linux armhf platform that uses GraalJS on a stock JDK (Liberica Standard JDK 17.0.6+10 arm 32 for Linux). We had been using the 21.2.0 release without issues, but decided to upgrade to 22.3.1 since we recently upgrade from Java 8 to Java 17.
Following the upgrade we found that our JS scripts/modules are now failing without providing any useful diagnostics. In particular we have been seeing the following error. The same application and JS scripts/modules run perfectly on Windows 10 and Ubuntu 20 machines with 64-bit Intel processors.
org.graalvm.polyglot.PolyglotException: java.lang.NoClassDefFoundError: Could not initialize class com.oracle.truffle.js.lang.JavaScriptLanguage
at app//com.oracle.truffle.js.lang.JavaScriptLanguageProvider.create(JavaScriptLanguageProvider.java:51)
at app//com.oracle.truffle.polyglot.LanguageCache.loadLanguage(LanguageCache.java:548)
at app//com.oracle.truffle.polyglot.PolyglotLanguageInstance.<init>(PolyglotLanguageInstance.java:100)
at app//com.oracle.truffle.polyglot.PolyglotLanguage.getInitLanguage(PolyglotLanguage.java:152)
at app//com.oracle.truffle.polyglot.PolyglotLanguage.ensureInitialized(PolyglotLanguage.java:142)
at app//com.oracle.truffle.polyglot.PolyglotLanguage.getOptionsInternal(PolyglotLanguage.java:134)
at app//com.oracle.truffle.polyglot.PolyglotLanguage.getOptionValues(PolyglotLanguage.java:202)
at app//com.oracle.truffle.polyglot.PolyglotContextConfig.getLanguageOptionValues(PolyglotContextConfig.java:407)
at app//com.oracle.truffle.polyglot.PolyglotSharingLayer.collectLanguageOptions(PolyglotSharingLayer.java:577)
at app//com.oracle.truffle.polyglot.PolyglotSharingLayer.claimLayerForContext(PolyglotSharingLayer.java:166)
at app//com.oracle.truffle.polyglot.PolyglotEngineImpl.claimSharingLayer(PolyglotEngineImpl.java:370)
at app//com.oracle.truffle.polyglot.PolyglotContextImpl.claimSharingLayer(PolyglotContextImpl.java:615)
at app//com.oracle.truffle.polyglot.PolyglotLanguageContext.ensureCreated(PolyglotLanguageContext.java:576)
at app//com.oracle.truffle.polyglot.PolyglotLanguageContext.ensureInitialized(PolyglotLanguageContext.java:691)
at app//com.oracle.truffle.polyglot.PolyglotContextImpl.eval(PolyglotContextImpl.java:1468)
at app//com.oracle.truffle.polyglot.PolyglotContextDispatch.eval(PolyglotContextDispatch.java:63)
at app//org.graalvm.polyglot.Context.eval(Context.java:399)
at app//org.graalvm.polyglot.Context.eval(Context.java:425)
While troubleshooting the problem we also found that GraalJS exception messages are garbled and contain what look to be Chinese characters. After a bit of debugging it appears that the problem is due to a byte ordering problem since reversing the order of each byte pair in the debugger results in ASCII text.
The garbled message problem is readily reproduced using the following snippet of code that intentionally triggers a coercion error:
Context context = Context.create(JavaScriptLanguage.ID);
Value result = context.eval(JavaScriptLanguage.ID, "new ArrayBuffer(10);");
result.asString();
Here is the message produced on the armhf platform:
java.lang.ClassCastException: Cannot convert '牁慲䉹晵敦筲'(language: JavaScript, type: ArrayBuffer) to Java type 'java.lang.String' using Value.asString(): Invalid coercion. You can ensure that the value can be converted using Value.isString().
And the expected error message on Windows 10:
java.lang.ClassCastException: Cannot convert 'ArrayBuffer{}'(language: JavaScript, type: ArrayBuffer) to Java type 'java.lang.String' using Value.asString(): Invalid coercion. You can ensure that the value can be converted using Value.isString().
We are still investigating the source of the NoClassDefFoundError exception, but believe it is likely related to the apparent byte ordering problem that is causing the garbled exception messages.