SpringNative 目前还是 bate 版本,请注意使用,勿应用于生产!
官方文档:https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/ 官方代码:https://github.com/spring-projects-experimental/spring-native/
经过 graalvm 编译打包后生产的 exe(windows)或 Linux 可执行程序,为单文件,可以随处拷贝直接运行,启动速度非常快。
本文简要的概述一个 demo 的完成过程
环境安装
1、安装和配置 maven(略)
2、下载 GraalVM (本文社区版 graalvm-ce-java17-22.1.0)
3、下载 Visual Studio Installer,Windows 打包 exe 需要 c++ 环境
官方下载地址:https://github.com/graalvm/graalvm-ce-builds/releases
解压 graalvm-ce-java17-windows-amd64-22.1.0.zip 后配置环境变量,将 JAVA_HOME 指向解压后的目录,将 %JAVA_HOME%\bin 追加到环境变量 Path 中(就是常规的 java 环境变量配置,只是把你 graalvm jdk 替代 java jdk 了)。
下载的 native-image-installable-svm-java17-windows-amd64-22.1.0.jar 文件在下面使用。
官方下载地址:https://visualstudio.microsoft.com/zh-hans/downloads/
运行下载的 VisualStudioSetup.exe
然后继续按照直至完成,结束后重启电脑(Windows 的东西就是烦)。
如下打开 “x64 Native Tools Command Prompt for VS 2022”
安装AOT编译器 native-image
命令操作
gu install或者在命令中直接在线联网按照(推荐)
gu install查看已经安装的 native-image 版本
native-image --version截图如下:
创建spring工程
使用 idea 创建,或者如下在 spring 官网上创建,组件添加 spring-native,为了验证项目运行,本例还添加了 webflux 做一个 /test/show 测试接口。
项目整体结构如下:
pom.xml 文件内容如下:
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springnative</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springnative</name>
<description>SpringNative project for Spring Boot</description>
<properties>
<java.version>17</java.version>
<repackage.classifier/>
<spring-native.version>0.12.0</spring-native.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-native</artifactId>
<version>${spring-native.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<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>
<plugin>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-aot-maven-plugin</artifactId>
<version>${spring-native.version}</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>
<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<profiles>
<profile>
<id>native</id>
<properties>
<repackage.classifier>exec</repackage.classifier>
<native-buildtools.version>0.9.9</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>
</project>
默认生成的 pom 中的 native-buildtools.version 为 0.9.11 我打包编译不成功,一直出现文末的错误,后来改成 0.9.9 后成功。
编译生成exe文件
还是打开 “x64 Native Tools Command Prompt for VS 2022”
在创建进行工程代码目录后执行命令 mvn clean package -DskipTests -Pnative 进行打包,然后要多等一会才能打包成功,这个打包速度也忒慢了,就一个普通 demo 就要好久,跟电脑的CPU和内存处理速度有关,就算电脑再好它也不快(执行过程中电脑变卡不要惊讶)。
运行测试
构建成功后,在项目的 target 目录中会看到对应的 exe 文件,双击即可打开运行,启动速度确实非常快!
然后浏览器访问 http://localhost:8080/test/show 验证结果。
其他问题
我使用 native-maven-plugin 的 0.9.12(截稿时最新)不能正常编译,报错如下(暂未找到问题原因):
Fatal error: Unsupported OptionOrigin: C:\Users\ADMINI~1\AppData\Local\Temp\native-image12860059531825023930args[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 18.721 s
[INFO] Finished at: 2022-07-07T09:21:29+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.graalvm.buildtools:native-maven-plugin:0.9.11:build (build-native) on project springnative: Execution of D:\JavaDev\jdk\graalvm-ce-java17-22.1.0\bin\native-image.cmd @C:\Users\ADMINI~1\AppData\Local\Temp\native-image12860059531825023930args returned non-zero result -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
后改成版本为 0.9.9 后成功,如有其他大佬知道问题原因和解决方法,欢迎留言指导,谢谢!
如果你只是体验 SpringNative GraalVM,记得体验完后将你的 JAVA_HOME 环境变量修改为你正常开发的 jdk,避免忘记修改导致问题。
(END)