GraalVM Setup and native image generation using Maven plugin
Today we are going to generate native image(one of many features of GraalVM) using GraalVM for the XML Parser that we developed earlier. Native image will contain the whole program in machine code ready for its immediate execution. It has the following advantages:Ref: https://www.graalvm.org/docs/why-graal/#create-a-native-image
- faster startup time
- no need for JVM(JDK/JRE) to execute the application
- low memory footprint
1) GraalVM setup
I used sdkman to install GraalVM SDK setup in my Linux machine. I used the following steps. First I listed all available JDK distributions and then I ran sdk install to install the latest GraalVM version. At the end of the installation I selected Yes to enable this version as default JDK.sdk list java
sdk install java 20.1.0.r11-grl
Then I verified the installation using following
java -version
I got the following. So, everything working great so far:
openjdk version "11.0.7" 2020-04-14
OpenJDK Runtime Environment GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02)
OpenJDK 64-Bit Server VM GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02, mixed mode, sharing)
If you want to do it manually, download the zip file and extract it and add to system path and enable that as default JDK.
2) Native image tools installation
Before you can use GraalVM native image utility, you need to have a working C developer environment. For this:- On Linux, you will need GCC, and the glibc and zlib headers.
Examples for common distributions:
# dnf (rpm-based)
sudo dnf install gcc glibc-devel zlib-devel libstdc++-static
# Debian-based distributions:
sudo apt-get install build-essential libz-dev zlib1g-dev
- On MacOS
XCode provides the required dependencies on macOS:
xcode-select --install
- On Windows, you will need to install the Visual Studio 2017 Visual C++ Build Tools
After this, you can run the following to install the native-image utility
$JAVA_HOME/bin/gu install native-image
Here, $JAVA_HOME is your GraalVM installation directory
3) Finally, use GraalVM native image Maven plugin to generate native-image during package phase
For this, I added the following on my XML Parser's pom.xml file:Dependency:
<dependency>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
<version>${graalvm.version}</version>
<scope>provided</scope>
</dependency>
Plugin: It automatically detects the jar file and the main class from the jar file. I've specified the imageName = xmltocsv as the executable
<plugin>
<groupId>org.graalvm.nativeimage</groupId>
<artifactId>native-image-maven-plugin</artifactId>
<version>${graalvm.version}</version>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
</execution>
</executions>
<configuration>
<!--The plugin figures out what jar files it needs to pass to the native image
and what the executable main class should be. -->
<!--<mainClass>${app.mainClass}</mainClass>-->
<imageName>xmltocsv</imageName>
<buildArgs>
--no-fallback
</buildArgs>
<skip>false</skip>
</configuration>
</plugin>
The version:
<graalvm.version>20.1.0</graalvm.version>
And ran with following to generate the native image
mvnw clean package native-image:native-image
It produced the following files on my target folder
── target
│ ├── xmltocsv //this is the binary file, it can run without jvm
│ └── xmltocsv-FINAL.jar //this required JVM to run
4) Testing
In my linux machine I executed the xmltocsv binary$ ./target/xmltocsv ../big3.xml ../big3.csv
It started faster, used less memory but took little longer(because we lost JVM optimizations) to convert the file than running the jar file to do the same.
The complete example code is available here: https://github.com/gtiwari333/java-read-big-xml-to-csv
No comments :
Post a Comment
Your Comment and Question will help to make this blog better...