graalvm 编译原生java graalvm win10 win 环境 搭建java11 java17 aot java 生成exe

交待一下

本文先用一个简单的java文件生成了exe,再搭建了maven项目,又把maven项目生成了EXE,整个没有什么毛病。。。就是坑有点多
其次,文中一会儿是vs2019一会儿又是vs2022 甚至还用了graalvm21,原因是,本文是多次迭代,使用过不同的版本,但总的流程和概念不变
遇到问题可以到群4915800 找我
另外可以去看我项目中关于native的配置

https://gitee.com/grateful/farcs

  • faros/pom.xml
  • faros/pub-dev/bulid-farcc-native.bat

关于原生程序运行时获取反射信息的问题

这个问题已经完美解决了,请看
https://www.cnblogs.com/cfas/p/16339789.html

graalvm组件介绍

这个自己去找资料

graalvm相关下载

https://github.com/graalvm/graalvm-ce-builds/releases/tag/vm-20.2.0

  • graalvm-ce-java17-windows-amd64-22.0.0.2
  • native-image-installable-svm-java17-windows-amd64-22.0.0.2.jar
    我是下载了这两个

关于C++编译器的环境变量

这个步骤必须成功,否则编译会失败。。
不知道gralvm是否支持clang编译,看网上大部分的文章都是用MSVC的编译器,都讲的是在环境变量中设置MSVC的地址,由于我之前编译过V8引擎,所以本地的C++环境有点乱,反正我是没设置成功。
我是直接装了VS2019,vs2022,至于装VS的那些组件的可以看这个文章
https://blog.csdn.net/qq_26212181/article/details/121418452

装了VS2019|vs2022 之后 WIN的菜单栏会有一个专门启动CL编译器的CMD工具
注意看,我用的是X64的 不是X64-X86的!

在这个地方找出来

也可以直接到VS目录下找,注意 不同的VS版本可能路径不同,大家可以搜索一下

配置graalVm环境变量

GRAALVM_HOME

JAVA_HOME和graalvmHOME一样 环境变量都一样
D:\AAAA_WORK\java\graalvm-ce-java17-windows-amd64-22.0.0.2\graalvm-ce-java17-22.0.0.2

## 安装依赖

执行下面的命令`gu.cmd` 这个玩意儿 网上的屌丝们 都是说gu  实际上要gu.cmd 谢特
 gu.cmd -L install native-image-installable-svm-java17-windows-amd64-22.0.0.2.jar
Processing Component archive: native-image-installable-svm-java17-windows-amd64-22.0.0.2.jar
Installing new component: Native Image (org.graalvm.native-image, version 22.0.0.2)

创建编译测试代码HelloWorld.java:

public class HelloWorld { 
    public static void main(String[] args) { 
        System.out.println("Hello World"); 
    }
}

编译HelloWorld为class

javac HelloWorld.java

进入到VS2019的专用编译工具(CMD)

输入 native-image HelloWorld
开始等待吧....

花了4分钟。。。。

执行生成的EXE

问题

  • Get-Unique : 找不到接受实际参数“install ”的位置形式参数。
    执行 gu 依赖管理时 出现的问题

大部分网上的文章 直接用的gu 其实在win下需要输入gu.cmd 坑爹把

命令行需要输入的是 gu.cmd
查看当前装了那些依赖
gu.cmd list

maven项目

本来想着用springboot项目生成exe的,但估计配置还有很多问题,所以先用maven项目试试

idea 搭建maven项目

https://www.cnblogs.com/lhboke/p/12858844.html

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

    <groupId>com.langs</groupId>
    <version>1.0-SNAPSHOT</version>
    <modelVersion>4.0.0</modelVersion>

    <properties>

        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>

    </properties>
    <artifactId>demo3</artifactId>



    <build>
        <finalName>native-image-js</finalName>

        <plugins>
            <plugin>
                <groupId>org.graalvm.nativeimage</groupId>
                <artifactId>native-image-maven-plugin</artifactId>
                <version>20.3.0</version>
                <configuration>
                    <!-- imageName用于设置生成的二进制文件名称 -->
                    <imageName>${project.artifactId}</imageName>
                    <!-- mainClass用于指定main方法类路径 -->
                    <mainClass>com.lang.Application</mainClass>
                    <!-- native image 编译参数文档:https://docs.oracle.com/en/graalvm/enterprise/20/docs/reference-manual/native-image/NativeImageMavenPlugin/ -->
                    <buildArgs>
                        --no-fallback
                    </buildArgs>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>native-image</goal>
                        </goals>
                        <phase>package</phase>
                    </execution>
                </executions>
            </plugin>


        </plugins>
    </build>
</project>

注意maven 项目的目录
src/main/java 这是必须的约定
否则生成的jar中不会有class 运行jar时,也会报找不到main class

maven项目生成EXE

这儿要注意使用的是前面提到的控制台工具,以及我是临时设置了graalvm的目录的。SET xxx=xxx 注意看图

为什么不能IDEA直接编译,因为需要用到VC编译器工具,除非在IDEA里面配置了这个环境才行
有网友解决了https://blog.csdn.net/weixin_43260887/article/details/137964533
编译有任何问题,可加上这两个参数,显示更详细的信息,我是加了下面的参数后报的

Error: Failed to find 'vcvarsall.bat' in a Visual Studio installation.
  --verbose  <!-- 显示详细构建日志 -->
  -H:+ReportExceptionStackTraces  <!-- 显示完整异常栈 -->

生成EXE前提是要打好jar包,因为环境配置的问题,直接在IDEA中使用maven插件生成package会报错。
直接在MS编译器的控制台上进入项目目录,执行mvn -Pnative clean package 即可,一次搞定

实际上就是调用的 这样的指令... graalvm团队的思路就是maven生成JAR 然后用下面的指令打包
native-image -cp native-image-js.jar Hello

我先按照maven的方式打包(注意 我所有的操作都在X64的VS的命令行工具下执行的)
mvn -Pnative clean package

生成后的EXE

出现问题

Image building on Java 11+ without native-image requires MAVEN_OPTS='--add-exports=java.base/jdk.internal.module=ALL-UNNAMED'

这个问题 总的说来是graalvm的BUG
把graalvm下的svm/bin下的native-image.exe 拷贝到 D:\AAAA_WORK\java\graalvm-ce-java17-windows-amd64-22.0.0.2\graalvm-ce-java17-22.0.0.2\bin 下面

对比下两个路径

D:\AAAA_WORK\java\graalvm-ce-java17-windows-amd64-22.0.0.2\graalvm-ce-java17-22.0.0.2\lib\svm\bin
D:\AAAA_WORK\java\graalvm-ce-java17-windows-amd64-22.0.0.2\graalvm-ce-java17-22.0.0.2\bin

这是graalvm对没有调起cmd那个文件引起的。

Error: Classes that should be initialized at run time got initialized during image building

出现这个情况 表示需要在编译参数中增加对应的类

class io.netty.util.internal.PlatformDependent0$6 cannot access class jdk.internal.misc.Unsafe (in module java.base) because module java.base does not export jdk.internal.misc to unnamed module

class io.netty.util.internal.PlatformDependent0$6 cannot access class jdk.internal.misc.Unsafe (in module java.base) because module java.base does not export jdk.internal.misc to unnamed module

这种情况是因为JAVA9以上的 三方包 需要在JVM编译参数中加上需要导入的module 上面就是缺少jdk.internal.misc.Unsafe

--add-exports=java.base/jdk.internal.misc.Unsafe=ALL-UNNAMED

最后做了个批处理文件来实现一键

前提还是要走IDEA编译出jar文件 且POM要有maven的native编译器插件,虽然最后会报错,但不影响.

@echo off
chcp 65001 >nul

:: 先切换到项目目录
cd /d "E:\AAAA_CODE\new-eclipse-workspace\farcs\faros"

:: 调用vcvars64.bat配置Visual Studio环境,根据自己的环境来
call "D:\vs2022\VC\Auxiliary\Build\vcvars64.bat"

:: 环境配置完成后,执行mvn命令
echo 开始执行Maven命令...
mvn -Pnative clean package

:: 暂停窗口,方便查看结果
pause
    

maven中的native编译插件


      <plugin>
      <!--该插件编译会报错,报错后需要用VS控制台编译,其他不影响-->
        <groupId>org.graalvm.nativeimage</groupId>
        <artifactId>native-image-maven-plugin</artifactId>
        <version>21.0.0.2</version>

        <configuration>

          <!-- imageName用于设置生成的二进制文件名称 -->
          <imageName>${project.artifactId}</imageName>
          <!-- mainClass用于指定main方法类路径 -->
          <mainClass>com.faros.App</mainClass>

          <!-- native image 编译参数文档:https://docs.oracle.com/en/graalvm/enterprise/20/docs/reference-manual/native-image/NativeImageMavenPlugin/ -->
          <buildArgs>

          --no-fallback

          --enable-url-protocols=http
          --enable-url-protocols=https
          <!--            &#45;&#45;initialize-at-run-time=ch.qos.logback,org.slf4j-->
          --initialize-at-build-time=ch.qos.logback.core.status.InfoStatus


          --initialize-at-build-time=ch.qos.logback.classic.Logger
          --initialize-at-build-time=ch.qos.logback.core.util.StatusPrinter
          --initialize-at-build-time=ch.qos.logback.classic.Level
          --initialize-at-build-time=ch.qos.logback.core.CoreConstants
          --initialize-at-build-time=org.slf4j.MDC
          --initialize-at-build-time=org.slf4j.LoggerFactory
          --initialize-at-build-time=ch.qos.logback.core.util.Loader
          --initialize-at-build-time=ch.qos.logback.core.spi.AppenderAttachableImpl
          --initialize-at-build-time=org.slf4j.impl.StaticLoggerBinder
          --trace-object-instantiation=ch.qos.logback.core.status.InfoStatus
          --verbose  <!-- 显示详细构建日志 -->
          -H:+ReportExceptionStackTraces  <!-- 显示完整异常栈 -->
          </buildArgs>




        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>native-image</goal>
            </goals>

            <phase>package</phase>
          </execution>
        </executions>
      </plugin>

参考

https://www.graalvm.org/docs/getting-started/
https://www.graalvm.org/reference-manual/native-image/
JAVAFX生成EXE 其中讲到了关于反射类和DLL的一些处理细节,值得一看
https://www.cnblogs.com/javalinux/p/15791024.html

posted @ 2022-04-16 23:53  方东信  阅读(4651)  评论(0)    收藏  举报