admin管理员组

文章数量:1122847

I've written a Java Chess program that plays fairly well. I wanted to use Graalvm to turn it into an exe so users wouldn't need to have Java installed to run it. A side benefit might be a little performance boost. The program compiles and runs fine from Java.

>javac chess.java
>jar -cfm chess.jar Manifest.txt *.class *.png *.wav *.txt *.ico
>java -jar chess.jar

It also compiles without errors using the native-image program.

>native-image -jar chess.jar
========================================================================================================================
GraalVM Native Image: Generating 'chess' (executable)...
========================================================================================================================
For detailed information and explanations on the build output, visit:
.md
------------------------------------------------------------------------------------------------------------------------
[1/8] Initializing...                                                                                    (7.0s @ 0.10GB)
 Java version: 21.0.5+9-LTS, vendor version: Oracle GraalVM 21.0.5+9.1
 Graal compiler: optimization level: 2, target machine: x86-64-v3, PGO: ML-inferred
 C compiler: cl.exe (microsoft, x64, 19.41.34123)
 Garbage collector: Serial GC (max heap size: 80% of RAM)
 1 user-specific feature(s):
 - com.oracle.svm.thirdparty.gson.GsonFeature
------------------------------------------------------------------------------------------------------------------------
Build resources:
 - 11.45GB of memory (75.6% of 15.16GB system memory, determined at start)
 - 12 thread(s) (100.0% of 12 available processor(s), determined at start)
[2/8] Performing analysis...  [****]                                                                     (9.3s @ 0.65GB)
    6,687 reachable types   (80.1% of    8,346 total)
   11,647 reachable fields  (59.6% of   19,530 total)
   35,214 reachable methods (53.7% of   65,575 total)
    2,102 types,    49 fields, and 1,059 methods registered for reflection
       69 types,    52 fields, and    59 methods registered for JNI access
        3 native libraries: crypt32, ncrypt, version
[3/8] Building universe...                                                                               (2.0s @ 0.62GB)
[4/8] Parsing methods...      [**]                                                                       (3.1s @ 0.82GB)
[5/8] Inlining methods...     [***]                                                                      (0.5s @ 1.17GB)
[6/8] Compiling methods...    [****]                                                                    (18.1s @ 0.88GB)
[7/8] Laying out methods...   [**]                                                                       (2.8s @ 1.31GB)
[8/8] Creating image...       [**]                                                                       (2.7s @ 1.60GB)
  19.47MB (58.36%) for code area:    19,031 compilation units
  13.58MB (40.70%) for image heap:  192,870 objects and 65 resources
 319.64kB ( 0.94%) for other data
  33.36MB in total
------------------------------------------------------------------------------------------------------------------------
Top 10 origins of code area:                                Top 10 object types in image heap:
   9.02MB java.desktop                                         4.92MB byte[] for code metadata
   6.55MB java.base                                            2.54MB byte[] for java.lang.String
   2.33MB svm.jar (Native Image)                               1.51MB java.lang.String
 641.66kB chess.jar                                            1.15MB java.lang.Class
 197.62kB com.oracle.svm.svm_enterprise                      349.00kB byte[] for reflection metadata
 153.15kB java.logging                                       329.12kB byte[] for general heap data
  72.82kB java.prefs                                         313.45kB com.oracle.svm.core.hub.DynamicHubCompanion
  64.82kB jdk.accessibility                                  265.19kB java.util.HashMap$Node
  56.90kB java.datatransfer                                  235.79kB byte[] for embedded resources
  50.44kB jdk.proxy1                                         216.59kB char[]
 236.70kB for 10 more packages                                 1.79MB for 1244 more object types
                              Use '-H:+BuildReport' to create a report with more details.
------------------------------------------------------------------------------------------------------------------------
Security report:
 - Binary includes Java deserialization.
 - Use '--enable-sbom' to embed a Software Bill of Materials (SBOM) in the binary.
------------------------------------------------------------------------------------------------------------------------
Recommendations:
 PGO:  Use Profile-Guided Optimizations ('--pgo') for improved throughput.
 INIT: Adopt '--strict-image-heap' to prepare for the next GraalVM release.
 AWT:  Use the tracing agent to collect metadata for AWT.
 HEAP: Set max heap for improved and more predictable memory usage.
 CPU:  Enable more CPU features with '-march=native' for improved performance.
------------------------------------------------------------------------------------------------------------------------
                        3.7s (7.9% of total time) in 182 GCs | Peak RSS: 2.89GB | CPU load: 5.82
------------------------------------------------------------------------------------------------------------------------
Produced artifacts:
 C:\Users\mike_\Dropbox\Projects\Chess\awt.dll (jdk_library)
 C:\Users\mike_\Dropbox\Projects\Chess\chess.exe (executable)
 C:\Users\mike_\Dropbox\Projects\Chess\fontmanager.dll (jdk_library)
 C:\Users\mike_\Dropbox\Projects\Chess\freetype.dll (jdk_library)
 C:\Users\mike_\Dropbox\Projects\Chess\java.dll (jdk_library_shim)
 C:\Users\mike_\Dropbox\Projects\Chess\javaaccessbridge.dll (jdk_library)
 C:\Users\mike_\Dropbox\Projects\Chess\javajpeg.dll (jdk_library)
 C:\Users\mike_\Dropbox\Projects\Chess\jawt.dll (jdk_library)
 C:\Users\mike_\Dropbox\Projects\Chess\jsound.dll (jdk_library)
 C:\Users\mike_\Dropbox\Projects\Chess\jvm.dll (jdk_library_shim)
 C:\Users\mike_\Dropbox\Projects\Chess\lcms.dll (jdk_library)
========================================================================================================================
Finished generating 'chess' in 46.1s.

>dir *.exe
 Volume in drive C has no label.
 Volume Serial Number is 3EE3-4511

 Directory of C:\Users\mike_\Dropbox\Projects\Chess

04/12/2024  14:10        34,979,840 chess.exe
               1 File(s)     34,979,840 bytes
               0 Dir(s)  1,912,119,099,392 bytes free

However I get errors when running the resulting exe.

>chess.exe
Exception in thread "main" java.lang.NoSuchMethodError: java.awt.Toolkit.getDefaultToolkit()Ljava/awt/Toolkit;
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.jni.functions.JNIFunctions$Support.getMethodID(JNIFunctions.java:1848)
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.jni.functions.JNIFunctions$Support.getMethodID(JNIFunctions.java:1833)
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.jni.functions.JNIFunctions.GetStaticMethodID(JNIFunctions.java:449)
        at [email protected]/java.awt.Toolkit.initIDs(Native Method)
        at [email protected]/java.awt.Toolkit.initStatic(Toolkit.java:1421)
        at [email protected]/java.awt.Toolkit.<clinit>(Toolkit.java:1393)
        at [email protected]/java.awt.Component.<clinit>(Component.java:624)
        at [email protected]/java.lang.Class.ensureInitialized(DynamicHub.java:604)
        at [email protected]/java.lang.Class.ensureInitialized(DynamicHub.java:604)
        at [email protected]/java.lang.Class.ensureInitialized(DynamicHub.java:604)
        at [email protected]/java.lang.invoke.DirectMethodHandle.ensureInitialized(DirectMethodHandle.java:288)
        at [email protected]/java.lang.invoke.DirectMethodHandle.internalMemberNameEnsureInit(DirectMethodHandle.java:336)

Would anyone with a little more experience be able to advise? I think it's something to do with native libraries being required for AWT calls but I'm not 100% sure what that is or how to fix it. Do I have to obtain java code for the AWT library and, if so, from where?

Sorry for the long question but I wanted to include everything.

Thanks for reading

Mike

What I tried and expected:

  • I obviously downloaded native-image.
  • I looked at the various examples.
  • I read elsewhere that other users had issues with AWT and JNI but no real answers given.
  • I tried getting native-image to work with my other Java projects but they're a little more complicated and create additional issues.
  • I also tried the launch4J tool to produce an exe but it seemed to want to install Java on users PC's.
  • What was I expecting? From the examples given I was expecting to point the native-image app at my working jar and obtain a working exe.

本文标签: How to get Graalvm to convert AWT Java program to exeStack Overflow