graalvm 编译原生java graalvm win10 win 环境 搭建java11 java17 aot java 生成exe
交待一下
本文先用一个简单的java文件生成了exe,再搭建了maven项目,又把maven项目生成了EXE,整个没有什么毛病。。。就是坑有点多
其次,文中一会儿是vs2019一会儿又是vs2022 甚至还用了graalvm21,原因是,本文是多次迭代,使用过不同的版本,但总的流程和概念不变
遇到问题可以到群4915800 找我
另外可以去看我项目中关于native的配置
- 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
<!-- --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
java新手自学群 626070845
java/springboot/hadoop/JVM 群 4915800
Hadoop/mongodb(搭建/开发/运维)Q群481975850
GOLang Q1群:6848027
GOLang Q2群:450509103
GOLang Q3群:436173132
GOLang Q4群:141984758
GOLang Q5群:215535604
C/C++/QT群 1414577
单片机嵌入式/电子电路入门群群 306312845
MUD/LIB/交流群 391486684
Electron/koa/Nodejs/express 214737701
大前端群vue/js/ts 165150391
操作系统研发群:15375777
汇编/辅助/破解新手群:755783453
大数据 elasticsearch 群 481975850
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。