oracle / graaljs

A ECMAScript 2024 compliant JavaScript implementation built on GraalVM. With polyglot language interoperability support. Running Node.js applications!
Universal Permissive License v1.0
1.78k stars 189 forks source link

org.graalvm.polyglot.Engine class not found! #762

Open dabugen opened 1 year ago

dabugen commented 1 year ago

Dear GraalVM Team,

I hope you are doing well. I would like to extend my gratitude for your continuous effort in making GraalVM the best JavaScript implementation available. I am truly impressed by the quality of your work.

Recently, I encountered an issue after installing GraalVM 23.1 (based on Java 21 version) and incorporating the NodeJS addon from this link: https://github.com/oracle/graaljs/releases/download/graal-23.1.0/graalnodejs-jvm-23.1.0-windows-amd64.zip.

Upon launching my NodeJS program, I received the following error message:

org.graalvm.polyglot.Engine class not found!
Exception in thread "main" java.lang.NoClassDefFoundError: org/graalvm/polyglot/Engine
Caused by: java.lang.ClassNotFoundException: org.graalvm.polyglot.Engine
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)

For your information, the NodeJS program runs smoothly with GraalVM 23.0.1 using NodeJS installed via the command line through GraalVM's bin directory (which doesn´t seem to be available anymore with 23.1). I am launching it with the following parameters:

C:\PortablePrograms\Java\languages\nodejs\bin\node.exe ^
--jvm ^
--vm.XX:+UseSerialGC ^
--vm.Xmx3800m ^
--vm.XX:+UnlockExperimentalVMOptions ^
--vm.XX:+DisableExplicitGC ^
--vm.XX:-UseJVMCINativeLibrary ^
--vm.XX:MaxNodeLimit=100000 ^
--vm.XX:-DontCompileHugeMethods ^
--vm.Dgraal.CompilerConfiguration=enterprise ^
--vm.Dgraal.UsePriorityInlining=true ^
--vm.Dgraal.Vectorization=true ^
--vm.Dgraal.OptDuplication=true ^
--vm.Dgraal.TuneInlinerExploration=1 ^
--vm.Dgraal.LoopRotation=true ^
--vm.Dgraal.StripMineCountedLoops=true ^
--vm.Dgraal.EarlyGVN=true ^
--vm.Dgraal.ConsiderVectorizableLoops=true ^
--vm.Dgraal.OptimizeVectorAPI=true ^
--engine.Mode=throughput ^
--experimental-options ^
.\bin\gen.js --settings .\lori-settings.ini

The issue arises when I switch to GraalVM 23.1 and incorporate NodeJS from the link mentioned above. I am uncertain about the cause of this problem and would greatly appreciate your guidance.

It is crucial for me to use the NodeJS implementation based on the GraalVM JVM, rather than the Native Image version, due to the heavy calculations my script performs and the extended runtime it requires. The JVM runtime parameters and optimizations I've implemented through extensive testing with version 23.0 have proven beneficial for this.

Thank you once again for your commitment to excellence. I look forward to your advice and guidance on this matter.

Best regards,

Lorenz

iamstolis commented 1 year ago

Recently, I encountered an issue after installing GraalVM 23.1 (based on Java 21 version) and incorporating the NodeJS addon from this link: https://github.com/oracle/graaljs/releases/download/graal-23.1.0/graalnodejs-jvm-23.1.0-windows-amd64.zip.

This is not an addon. This is a standalone version of graal-nodejs on top of GraalVM 23.1. If you want to use graalnodejs then this artifact should be enough. There is no need to "incorporate" it somewhere (which is most likely the culprit of the issue that you are facing).

dabugen commented 1 year ago

Thank you for the assistance, but the project was anyway already located in a distinct directory, just beneath the main GraalVM directory, though it remained isolated. Relocating it to an entirely new directory, which involved unpacking it from scratch as a precautionary measure, yielded no discernible difference, as the same error persisted.

However, I managed to identify the root cause of the issue. It turns out that modifying the command line parameter from "--vm.XX:-UseJVMCINativeLibrary" to "--vm.XX:+UseJVMCINativeLibrary" resolved the problem, and everything now functions as expected.

My current concern pertains to the documentation, which suggests that using "--vm.XX:+UseJVMCINativeLibrary" opts for the precompiled (native) library, rather than allowing the Graal compiler to optimize itself by avoiding the use of the precompiled native library. I'd greatly appreciate it if someone from the Oracle team could provide insights or comments regarding this matter. I've always regarded this option as a valuable performance enhancement for long-running projects that are in need of maximum throughput instead of fast startup. Many thanks.

iamstolis commented 1 year ago

I am sorry, I am still not able to reproduce the mentioned exception:

node.exe --vm.XX:-UseJVMCINativeLibrary
Cannot use JVMCI compiler: No JVMCI compiler found

I am getting the same result on both Windows and Linux. I assume that this result is expected i.e. that the standalone distribution of graal-nodejs does not contain jargraal.

My current concern pertains to the documentation, which suggests that using "--vm.XX:+UseJVMCINativeLibrary" opts for the precompiled (native) library, rather than allowing the Graal compiler to optimize itself by avoiding the use of the precompiled native library. I'd greatly appreciate it if someone from the Oracle team could provide insights or comments regarding this matter. I've always regarded this option as a valuable performance enhancement for long-running projects that are in need of maximum throughput instead of fast startup.

It is recommended to use libgrall/-XX:+UseJVMCINativeLibrary. Note that this option affects the compilation of the compiler itself only i.e. it has no impact on the code produced by the compiler (which is what matters for a long running application).

dabugen commented 1 year ago

I appreciate your prompt response. Today, I plan to conduct a series of performance tests to gauge the impact of using libgraal as opposed to allowing the compiler to optimize itself without relying on this precompiled library in my NodeJS application. Based on my experience with previous Graal releases, I consistently observed a 5% performance improvement when avoiding the use of libgraal. It will be interesting to see if this trend holds true in this case. Let's find out...

dabugen commented 1 year ago

I have conducted comprehensive tests on my application, which involves intensive calculations (number crunching for the development of an automated trading system). This application runs continuously on my computer, utilizing both NodeJS running on GraalVM 23.0.1 with the "-UseJVMCINativeLibrary" flag and the new standalone 23.1 NodeJS Enterprise version, available at https://github.com/oracle/graaljs/releases/download/graal-23.1.0/graalnodejs-jvm-23.1.0-windows-amd64.zip.

The results of my testing indicate that GraalVM 23.0.1 with the "-UseJVMCINativeLibrary" flag is 6% faster than version 23.1.0, which no longer supports the "-UseJVMCINativeLibrary" option. Consequently, version 23.1.0 can rely solely on the precompiled, non-self-optimizing compiler. This performance disparity is equivalent to running version 23.0.1 with the "+UseJVMCINativeLibrary" option enabled and hence using the precompiled libgraal.

I would like to inquire whether the Oracle Team intends to reintroduce this feature. It would be unfortunate to experience a 6% performance decrease if I wish to leverage the new version for its additional features while being compelled to stick with version 23.0.1 for optimal performance.

Thank you for your attention to this matter.