1.配置环境

首先下载graalvm并配置环境变量,由于网络原因我们还需在github下载native-image

这里使用的是

graalvm-ce-java17-windows-amd64-22.3.2.zip

native-image-installable-svm-java17-windows-amd64-22.3.2.jar

打开终端(cmd或者powershell)若网络环境比较好则直接安装

联网安装
gu install native-image
本地安装
gu install --file native-image-installable-svm-java17-windows-amd64-22.3.2.jar

验证是否安装成功

$ native-image
Please specify options for native-image building or use --help for more info.

下载VisualStudio,安装时选择c++的桌面开发

安装完会有x64 Native Tools Command Prompt for VS 2022工具,打开此工具进入到我们需要打包的jar文件的目录下

若在linux平台下需要gcc等环境

sudo yum install gcc glibc-devel zlib-devel
2.打包

打包jar命令格式为

native-image -cp [jar包名] [全限定主类名] [-o可选,输出] [输出名] [--no-fallback 可选,可以在没有jdk环境的机器上运行]
或者
native-image -jar [jar包] [-o可选,输出] [输出名] [--no-fallback 可选,可以在没有jdk环境的机器上运行]

例:

#编译jar包
D:\abc>ls
TestNative.jar  Tetris.jar  jadx-gui-devs.jar

D:\abc>native-image -cp jadx-gui-devs.jar jadx.gui.JadxGUI -o jadx-gui
#编译某个类【必须有main入口方法,否则无法编译】
native-image -cp .\classes org.example.App

打包maven项目

直接maven clean->complie->package就ok了

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>graalvmTest</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <graalvm.version>21.2.0</graalvm.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.graalvm.sdk</groupId>
            <artifactId>graal-sdk</artifactId>
            <version>${graalvm.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.graalvm.nativeimage</groupId>
                <artifactId>native-image-maven-plugin</artifactId>
                <version>${graalvm.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>native-image</goal>
                        </goals>
                        <phase>package</phase>
                    </execution>
                </executions>
                <configuration>
                    <skip>false</skip>
					<imageName>${project.artifactId}</imageName>
                    <mainClass>主函数全面限类名</mainClass>
                    <buildArgs>
                        --no-fallback
                    </buildArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

复杂项目的问题

打包的exe如果有反射等用法,很容易发生ClassNotFound的报错

Graalvm通过静态分析提前编译来为Java应用程序构建高度优化的本机可执行文件,这就需要在编译时就知道所有的程序类型,而java中的反射、动态代理等功能,在编译时不确定具体的类型,所以在使用GraalVm构建native image前需要通过配置列出反射可见的所有类型。而程序内置提供了agentlib

使用agentlib打包跟踪jvm生成配置文件
java -agentlib:native-image-agent=config-output-dir=.\peizhi\ -jar [jar包]
会在peizhi目录下生成json配置文件
|-D:\ecj\ECJ\target\peizhi
	|-agent-extracted-predefined-classes
	|-jni-config.json
	|-predefined-classes-config.json
	|-proxy-config.json
	|-reflect-config.json
	|-resource-config.json
	|-serialization-config.json

META-INF中的native-image中新增带有groupid和artifactId的路径,并且将配置文件粘贴

结构
META-INF
    ├─maven
    │  └─org.eclipse
    │      └─ECJ
    └─native-image
        ├─org.eclipse <groupId>
        └─ECJ <artifactId>
        	|-jni-config.json
            |-predefined-classes-config.json
            |-proxy-config.json
            |-reflect-config.json
            |-resource-config.json
            |-serialization-config.json
        	

打包

native-image -jar  [jar包] --no-fallback

如果出现报错

Error:Class initialization of io.netty.util.internal.logging.Log4JLogger failed. Use the option --initialize-at-run-time=io.netty.util.internal.logging.logging.Log4JLogger to explicitly requeset delayed initialization of this class

则需要添加参数

native-image -jar  [jar包] --no-fallback --initialize-at-run-time=io.netty.util.internal.logging.logging.Log4JLogger --allow-incomplete-classpath
3.整合SpringBoot

1.配置环境

需要修改三个环境变量PathINCLUDElib

  • 1、 Path:添加如下值

    • C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\bin\Hostx64\x64
  • 2、新建INCLUDE环境变量:值为

  • C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\include;
    C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared;
    C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt;
    C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um;
    C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\winrt
    

    3、新建lib环境变量:值为

    C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\lib\x64;
    C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64;
    C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x64
    

    其中环境变量为VisualStudio安装目录下的头文件以及库

2.引入依赖

<build>
    <plugins>
        <plugin>
            <groupId>org.graalvm.buildtools</groupId>
            <artifactId>native-maven-plugin</artifactId>
         </plugin>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

在idea中勾选maven->配置文件->native,然后package打包,选择插件->native->native:compile-no-fork

即可打包成功

也可以直接进入到项目目录使用命令来打包

mvn -Pnative native:compile-no-fork -f pom.xml

人生不作安期生,醉入东海骑长鲸