Introduction
GraalVM
is a high-performance JDK that supports Java/Python/JavaScript and other languages. It allows Java to be turned into a binary file for execution, making programs run faster anywhere. This may be a war between Java and Go?
Download and install GraalVM
Install GraalVM
First of all, go to the official website to download, I downloaded it directly from GitHub Release Page, please download the corresponding system package, I downloaded the following.
graalvm-ce-java11-darwin-amd64-22.3.0.tar.gz
Download and extract to some directory, mine is as follows.
/Users/larry/Software/graalvm-ce-java11-22.3.0
Then test if the corresponding program can be executed properly, such as java --version
. On a Mac the following error will occur.
1
|
is damaged and can't be opened.
|
So the following statement needs to be executed.
1
|
$ sudo xattr -r -d com.apple.quarantine /Users/larry/Software/graalvm-ce-java11-22.3.0
|
Note the modification of the corresponding directory.
Then it will be ready for execution.
1
2
3
4
|
$ ./java --version
openjdk 11.0.17 2022-10-18
OpenJDK Runtime Environment GraalVM CE 22.3.0 (build 11.0.17+8-jvmci-22.3-b08)
OpenJDK 64-Bit Server VM GraalVM CE 22.3.0 (build 11.0.17+8-jvmci-22.3-b08, mixed mode, sharing)
|
Install native-image
This tool is used to convert Java programs into native binary packages and is installed as follows.
1
2
3
4
5
|
$ ./gu install native-image
Downloading: Component catalog from www.graalvm.org
Processing Component: Native Image
Downloading: Component native-image: Native Image from github.com
Installing new component: Native Image (org.graalvm.native-image, version 22.3.0)
|
Since this GraalVM is not mature enough and I don’t want to use it all the time, I switch it by one command, configured as follows.
1
2
3
4
5
6
|
export GraalVM_HOME=/Users/larry/Software/graalvm-ce-java11-22.3.0/Contents/Home
alias switchOnGraalVM='export PATH=$GraalVM_HOME:$PATH'
alias switchOnGraalVMJavaHome='export JAVA_HOME=/Users/larry/Software/graalvm-ce-java11-22.3.0/Contents/Home'
alias switchOffGraalVM='export PATH=`echo $PATH | tr ":" "\n" | grep -v "graalvm" | tr "\n" ":"`'
alias switchOffGraalVMJavaHome='export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home'
|
Configuring IDEA
You can configure the corresponding JDK on IDEA so that you can use it when developing.
Integrating Spring Native with Spring Boot
Common Spring Boot application
New to create a common Spring Boot web application, the main Java code is as follows.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@SpringBootApplication
@RestController
@RequestMapping("/")
public class SpringbootNativeGraalVMMain {
public static void main(String[] args) {
SpringApplication.run(SpringbootNativeGraalVMMain.class, args);
}
@GetMapping("/hi-graalvm")
public String hi() {
return "This message is from Spring Boot built/run by GraalVM/Spring Native";
}
}
|
The boot time is 1.193 seconds, which is not bad. My computer is not bad.
Integrating Spring Native
Adding dependencies.
1
2
3
4
5
|
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-native</artifactId>
<version>${spring-native.version}</version>
</dependency>
|
Add the plug-in, which is very important, otherwise various errors will occur.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<build>
<plugins>
<plugin>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-aot-maven-plugin</artifactId>
<version>0.11.5</version>
<executions>
<execution>
<id>test-generate</id>
<goals>
<goal>test-generate</goal>
</goals>
</execution>
<execution>
<id>generate</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
|
Add the following plugins to build executable programs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
<profiles>
<profile>
<id>native</id>
<properties>
<repackage.classifier>exec</repackage.classifier>
<native-buildtools.version>0.9.11</native-buildtools.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>${native-buildtools.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>test-native</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
</execution>
<execution>
<id>build-native</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
|
Then build the executable with the following command, which will take a bit longer.
1
|
$ mvn clean package -Pnative
|
The build completed in about two minutes or so, and an executable was generated. Run it with the following command.
1
|
$ target/spring-boot-native-graalvm
|
It turned out to take only 0.066 seconds, or 66 milliseconds to do so, which is too fast.
The http service is working fine.
Running with Docker
Run the local Docker first and then add the dependencies as follows.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>${repackage.classifier}</classifier>
<image>
<builder>paketobuildpacks/builder:tiny</builder>
<env>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
</env>
</image>
</configuration>
</plugin>
|
Build the Docker image with the following command.
1
|
mvn spring-boot:build-image
|
It may take a long time, you need to download some tools and images.
After a successful build, you can see that the new image has been added.
1
2
|
$ docker images | grep graalvm
spring-boot-native-graalvm 1.0-SNAPSHOT d2c8d5c52a3c 42 years ago 85.8MB
|
Use the following command to run the image.
1
|
$ docker run --rm spring-boot-native-graalvm:1.0-SNAPSHOT -p 8080:8080
|
The startup time is 59ms, which is even shorter.
Some notes
- Directly convert jar package to executable by
native-image
command, if you encounter various problems, you are advised to give up trying, which is the value of Spring Native
existence.
- Be careful to switch the corresponding Java program and Java Home, otherwise the build will be abnormal.
- From the package name
experimental
of Spring Native, it is still experimental and there should be some time before it is applied to production environment, so don’t use it easily on production.
Complete Code
The code can be found on GitHub: https://github.com/LarryDpk/pkslow-samples
Reference: https://www.cnblogs.com/larrydpk/p/17073451.html