GraalVM code examples ⬆
Directory examples\ contains GraalVM code examples coming from various websites - mostly from the GraalVM project and tested on a Windows machine.
|
In this document we present the following code examples in more detail:
Project ClassInitialization\
consists of the two classes HelloStartupTime.java
and HelloCachedTime.java
.
🔎 The example comes from Christian Wimmer's article "Updates on Class Initialization in GraalVM Native Image Generation", published on September 12, 2019.
Command build.bat
with no argument displays the help message with the available options and subcommands (same result as build help
):
> build Usage: build { <option> | <subcommand> } Options: -cached select main class with cached startup time -debug print commands executed by this script -jvmci add JVMCI options -native generate both JVM files and native image -timer print total execution time -verbose print progress messages Subcommands: clean delete generated files compile generate executable doc generate HTML documentation help print this help message lint analyze Java source files with CheckStyle run run the generated executable test execute JMH benchmarks
Command build.bat clean run
produces the following output:
> build clean run Startup: Fri Nov 15 22:43:31 CET 2019 Now: Fri Nov 15 22:43:31 CET 2019
Command build.bat -verbose clean run
also displays progress messages:
> build -verbose clean run Delete directory target Compile 2 Java source files to directory "target\classes" Execute Java main class org.graalvm.example.HelloStartupTime Copy resource files to directory "target\classes" Execute Java main class org.graalvm.example.HelloStartupTime Startup: Fri Nov 15 22:43:48 CET 2019 Now: Fri Nov 15 22:43:48 CET 2019
Command build -native clean compile
generates the native image target\HelloStartupTime.exe
for source file HelloStartupTime.java
:
> build -native clean compile > tree /a /f target | findstr /v "^[A-Z]" | HelloStartupTime.exe | HelloStartupTime.exp | HelloStartupTime.lib | HelloStartupTime.obj | HelloStartupTime.pdb | HelloStartupTime.tmp | source_list.txt | \---classes \---org \---graalvm \---example HelloStartupTime.class Startup.class > target\HelloStartupTime.exe Startup: Fri Nov 15 22:50:01 CET 2019 Now: Fri Nov 15 22:50:01 CET 2019
Command build.bat -native -cached clean compile
generates the native image target\HelloCachedTime.exe
for source file HelloCachedTime.java
:
> build -native -cached clean compile > tree /a /f target | findstr /v "^[A-Z]" | HelloCachedTime.exe | HelloCachedTime.exp | HelloCachedTime.lib | HelloCachedTime.obj | HelloCachedTime.pdb | HelloCachedTime.tmp | source_list.txt | \---classes \---org \---graalvm \---example HelloCachedTime.class Startup.class > target\HelloCachedTime.exe Startup: Fri Nov 15 22:53:31 CET 2019 Now: Fri Nov 15 22:53:31 CET 2019
Command build -native -debug compile
shows the the settings of commands javac.exe
and native-image.cmd
during the generation of executable target\HelloStartupTime.exe
:
> build -native -debug compile [build] Options : _CACHED=0 _TARGET=native _TIMER=0 _VERBOSE=0 [build] Subcommands: _CLEAN=0 _COMPILE=1 _DOC=0 _LINT=0 _PACK=0 _RUN=0 _TEST=0 [build] Variables : "GRAALVM_HOME=C:\opt\jdk-graalvm-ce-17.0.9_9.1" [build] Variables : "JAVA_HOME=C:\opt\jdk-graalvm-ce-17.0.9_9.1" [build] Variables : "MSVS_HOME=X:" [build] Variables : _MAIN_CLASS=org.graalvm.example.HelloStartupTime [build] 00000000000000 Target : 'G:\examples\ClassInitialization\target\classes\.latest-build' [build] 20191115223804 Sources: 'G:\examples\ClassInitialization\src\main\java\*.java' [build] _COMPILE_REQUIRED=1 [build] "C:\opt\jdk-graalvm-ce-17.0.9_9.1\bin\javac.exe" "@G:\examples\ClassInitialization\target\javac_opts.txt" "@G:\examples\ClassInitialization\target\javac_sources.txt" [build] "X:\VC\Auxiliary\Build\vcvarsall.bat" x64 ********************************************************************** ** Visual Studio 2019 Developer Command Prompt v16.0 ** Copyright (c) 2021 Microsoft Corporation ********************************************************************** [vcvarsall.bat] Environment initialized for: 'x64' [build] INCLUDE="X:\\VC\Tools\MSVC\14.28.29910\ATLMFC\include;..." [build] LIB="X:\\VC\Tools\MSVC\14.28.29910\ATLMFC\lib\x64;..." [build] LIBPATH="X:\\VC\Tools\MSVC\14.28.29910\ATLMFC\lib\x64;..." [build] "C:\opt\graalvm-ce-java11-22.3.2\bin\native-image.cmd" --trace-class-initialization --initialize-at-build-time=org.graalvm.example --initialize-at-run-time=org.graalvm.example.Startup -cp G:\examples\ClassInitialization\target\classes org.graalvm.example.HelloStartupTime G:\examples\ClassInitialization\target\HelloStartupTime [G:\examples\ClassInitialization\target\HelloStartupTime:12076] classlist: 1,423.32 ms, 1.16 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] (cap): 7,889.67 ms, 1.16 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] setup: 9,858.53 ms, 1.16 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] (clinit): 153.50 ms, 1.49 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] (typeflow): 4,169.94 ms, 1.49 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] (objects): 3,461.33 ms, 1.49 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] (features): 220.37 ms, 1.49 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] analysis: 8,152.19 ms, 1.49 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] universe: 415.99 ms, 1.57 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] (parse): 766.40 ms, 1.57 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] (inline): 898.37 ms, 1.58 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] (compile): 5,273.11 ms, 1.82 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] compile: 7,280.26 ms, 1.82 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] image: 630.74 ms, 1.82 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] write: 1,235.45 ms, 1.82 GB [G:\examples\ClassInitialization\target\HelloStartupTime:12076] [total]: 29,404.27 ms, 1.82 GB [build] _EXITCODE=0
CountUppercase
Example ▲
Project CountUppercase\
is a micro-benchmark:
- system property
iterations
defines how many times the counting test is performed. - program arguments are concatenated into a sentence which is used as test input.
Command build.bat
with no argument displays the help message with the available options and subcommands (same result as build help
):
> build Usage: build { <option> | <subcommand> } Options: -debug print commands executed by this script -jvmci add JVMCI options -native generate both JVM files and native image -timer print total execution time -verbose print progress messages Subcommands: clean delete generated files compile generate executable doc generate HTML documentation help print this help message lint analyze Java source files with CheckStyle run run executable
Command build.bat clean run
produces the following output (system property iterations=5
by default):
> build clean run -- iteration 1 -- 1 (375 ms) 2 (187 ms) 3 (141 ms) 4 (172 ms) 5 (140 ms) 6 (141 ms) 7 (187 ms) 8 (141 ms) 9 (141 ms) total: 69999993 (1750 ms) [...] -- iteration 5 -- 1 (125 ms) 2 (188 ms) 3 (125 ms) 4 (140 ms) 5 (141 ms) 6 (125 ms) 7 (140 ms) 8 (125 ms) 9 (141 ms) total: 69999993 (1375 ms)
🔎 Executing the above command with option
-debug
also displays operations performed internally. The interesting parts are prefixed with label[build]
(e.g.-Diterations=5
):> build run -debug | findstr /b "[debug]" [build] Properties : _PROJECT_NAME=CountUppercase _PROJECT_VERSION=1.0-SNAPSHOT [build] Options : _TIMER=0 _VERBOSE=0 [build] Subcommands: clean compile_jvm run_jvm [build] Variables : "GRAALVM_HOME=C:\opt\jdk-graalvm-ce-17.0.9_9.1" [build] Variables : "JAVA_HOME=C:\opt\jdk-graalvm-ce-17.0.9_9.1" [...] [build] C:\opt\jdk-graalvm-ce-17.0.9_9.1\bin\javac.exe -d G:\examples\CountUppercase\target\classes @G:\examples\CountUppercase\target\source_list.txt [build] C:\opt\jdk-graalvm-ce-17.0.9_9.1\bin\java.exe -cp G:\examples\CountUppercase\target\classes -Diterations=5 -Dgraal.ShowConfiguration=info -Dgraal.PrintCompilation=true -Dgraal.LogFile=G:\examples\CountUppercase\target\graal_log.txt CountUppercase In 2019 I would like to run ALL languages in one VM. [build] Compilation log written to G:\examples\CountUppercase\target\graal_log.txt [build] _EXITCODE=0
Command build.bat -verbose lint
analyzes the source files with our custom CheckStyle configuration 1:
> build -verbose lint Analyze 1 Java source file with CheckStyle configuration "%LOCALAPPDATA%\Checkstyle\graal_checks.xml" Starting audit... Audit done.
🔎 Directory
%LOCALAPPDATA%\Checkstyle
contains both the CheckStyle configuration filegraal_checks.xml
and the CheckStyle librarycheckstyle-*-all.jar
:> dir /b %USERPROFILE%\.graal checkstyle-10.2-all.jar graal_checks.xml > more %USERPROFILE%\.checkstyle\graal_checks.xml <?xml version="1.0"?> <!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd"> <module name="Checker"> <property name="localeCountry" value="US"/> <property name="localeLanguage" value="en"/> <property name="severity" value="error"/> ... <module name="TreeWalker"> ... </module> </module>
NiceMessage
Example ▲
Example NiceMessage
illustrates how dynamic class loading is handled by the native-image
tool when generating the native variant of a Java application.
🔎 The example comes from Vega's blog post "Building native images in Java with GraalVM", published on February 3, 2023.
Command build.bat clean run
builds and executes the JVM variant of the Java application (target\Application.jar
):
> build -verbose clean run Delete directory "target" Compile 4 Java source files to directory "target\classes" Copy resource files to directory "target\classes" Execute Java main class "dev.danvega.Application" MeanMessage This is a mean message!
🔎 Passing the special GraalVM option
-agentlib:native-image-agent=...
when running the JVM application generates useful metadata information; in particular the fileMETA-INF\native-image\reflect-config.json
will be needed when generating the native application.> tree /a /f target\META-INF |findstr /v "^[A-Z]" \---native-image | jni-config.json | predefined-classes-config.json | proxy-config.json | reflect-config.json | resource-config.json | serialization-config.json | \---agent-extracted-predefined-classes
Command build.bat -native clean run
builds and executes the native variant of the Java application (target\Application.exe
):
🔎 The configuration file
META-INF\native-image\reflect-config.json
enumerates the two class variants which may be dynamically loaded inApplication.java
.[ { "name":"dev.danvega.MeanMessage", "methods":[ {"name":"","parameterTypes":[] }, {"name":"printMessage","parameterTypes":[] } ] }, { "name":"dev.danvega.NiceMessage", "methods":[ {"name":"","parameterTypes":[] }, {"name":"printMessage","parameterTypes":[] } ] } ]
> build -verbose -native run No action required ('src\main\java\*.java','src\main\resources\*') No action required ('target\classes\*') This is a mean message! > target\Application.exe NiceMessage This is a nice message! > target\Application.exe MeanMessage This is a mean message!
Ranking
Example ▲
Project Ranking\
is a micro-benchmark.
🔎 The example comes from Berger's article "An introduction to GraalVM", published on June 28, 2019.
Command build.bat
with no argument displays the help message with the available options and subcommands (same result as build help
):
> build Usage: build { <option> | <subcommand> } Options: -debug print commands executed by this script -jvmci add JVMCI options -native generate both JVM files and native image -timer print total execution time -verbose print progress messages Subcommands: clean delete generated files compile generate executable doc generate HTML documentation help print this help message lint analyze Java source files with CheckStyle test execute micro benchmark
Command build.bat clean run
builds and executes the JVM variant of the JMH benchmark (target\benchmarks.jar
):
> build -verbose clean run Delete directory "target" Compile 2 Java source files to directory "target\classes" Create Java archive "target\benchmarks.jar" Copy chart file to directory "target" Execute JMH benchmark (JVM) # JMH version: 1.35 # VM version: JDK 11.0.16, OpenJDK 64-Bit Server VM, 11.0.16+8-jvmci-22.2-b06 # VM invoker: C:\opt\graalvm-ce-java11-22.3.2\jre\bin\java.exe # VM options: -XX:ThreadPriorityPolicy=1 [...] -Xmx1G # Warmup: 3 iterations, 10 s each # Measurement: 3 iterations, 10 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Average time, time/op # Benchmark: nl.avisi.Ranking.rank # Run progress: 0.00% complete, ETA 00:01:00 # Fork: 1 of 1 # Warmup Iteration 1: files=[G:\examples\Ranking\target\chart2000-songyear-0-3-0058.csv] 13.601 ms/op # Warmup Iteration 2: 11.303 ms/op # Warmup Iteration 3: 11.644 ms/op Iteration 1: 11.605 ms/op Iteration 2: 11.700 ms/op Iteration 3: 11.817 ms/op Result "nl.avisi.Ranking.rank": 11.707 ±(99.9%) 1.934 ms/op [Average] (min, avg, max) = (11.605, 11.707, 11.817), stdev = 0.106 CI (99.9%): [9.773, 13.641] (assumes normal distribution) # Run complete. Total time: 00:01:00 ... Benchmark Mode Cnt Score Error Units Ranking.rank avgt 3 11.707 ± 1.934 ms/op
Command build.bat -verbose -native clean run
builds and executes the native variant of the JMH benchmark (target\Ranking.exe
):
> build -verbose -native clean run Delete directory "target" Compile 2 Java source files to directory "target\classes" Create Java archive "target\benchmarks.jar" Create native image "target\Ranking" =============================================================================================== GraalVM Native Image: Generating 'G:\examples\Ranking\target\Ranking' (executable)... =============================================================================================== [1/7] Initializing... (15,5s @ 0,21GB) Version info: 'GraalVM 22.3.2 Java 11 CE' C compiler: cl.exe (microsoft, x64, 19.29.30141) Garbage collector: Serial GC [2/7] Performing analysis... [*********] (16,5s @ 1,59GB) 3 828 (80,78%) of 4 739 classes reachable 5 169 (50,96%) of 10 143 fields reachable 17 994 (51,95%) of 34 640 methods reachable 155 classes, 0 fields, and 527 methods registered for reflection 71 classes, 57 fields, and 59 methods registered for JNI access [3/7] Building universe... (1,4s @ 1,85GB) [4/7] Parsing methods... [*] (1,2s @ 0,79GB) [5/7] Inlining methods... [****] (1,3s @ 1,84GB) [6/7] Compiling methods... [****] (13,1s @ 1,52GB) [7/7] Creating image... (3,8s @ 1,88GB) 6,98MB (41,72%) for code area: 10 718 compilation units 8,53MB (50,99%) for image heap: 2 396 classes and 110 351 objects 1,22MB ( 7,28%) for other data 16,73MB in total ------------------------------------------------------------------------------------------------ Top 10 packages in code area: Top 10 object types in image heap: 717,91KB java.util 1,42MB byte[] for code metadata 421,83KB com.sun.crypto.provider 1,08MB byte[] for general heap data 398,16KB com.oracle.svm.jni 1,03MB java.lang.String 378,81KB java.lang 846,91KB java.lang.Class 308,90KB java.io 697,47KB byte[] for java.lang.String 261,61KB java.util.concurrent 342,33KB java.util.HashMap$Node 226,13KB java.util.regex 328,97KB com.oracle.svm.core.hub.DynamicHubCompanion 224,21KB java.text 204,16KB java.lang.String[] 220,99KB org.openjdk.jmh.runner 198,84KB java.util.concurrent.ConcurrentHashMap$Node 211,82KB com.oracle.svm.core.reflect 168,16KB java.util.HashMap$Node[] ... 148 additional packages ... 889 additional object types (use GraalVM Dashboard to see all) ------------------------------------------------------------------------------------------------ 2,7s (4,8% of total time) in 19 GCs | Peak RSS: 4,12GB | CPU load: 4,83 ------------------------------------------------------------------------------------------------ Produced artifacts: G:\examples\Ranking\target\Ranking.exe (executable) G:\examples\Ranking\target\sunmscapi.dll (jdk_lib) G:\examples\Ranking\target\Ranking.build_artifacts.txt ================================================================================================ Finished generating 'G:\examples\Ranking\target\Ranking' in 54,9s. Execute JMH benchmark "target\Ranking.exe" Exception in thread "main" java.lang.ExceptionInInitializerError at org.openjdk.jmh.runner.options.CommandLineOptions.<init>(CommandLineOptions.java:99) at org.openjdk.jmh.Main.main(Main.java:41) Caused by: java.lang.IllegalArgumentException: int is not a value type at joptsimple.internal.Reflection.findConverter(Reflection.java:66) at org.openjdk.jmh.runner.options.IntegerValueConverter.<clinit>(IntegerValueConverter.java:35) ... 2 more
[1] CheckStyle configuration ↩
-
The CheckStyle tool is available as a Java archive file
checkstyle-*-all.jar
which contains two example configuration files: -
sun_checks.xml
(Sun Code Conventions) andgoogle_checks.xml
(Google Java Style).
-
Note that the full CheckStyle distribution (aka "
checkstyle-all
") is not available from Maven Central and must be retrieved separately.