graalvm 编译原生java 解决反射的问题 maven配置
2022/6/4 1:22:25
本文主要是介绍graalvm 编译原生java 解决反射的问题 maven配置,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
由来
之前已经采坑完成了基于maven项目的java 二进制编译,但实际上基于原生的程序,在运行时是无法进行反射的,需要单独生成配置文件
手动配置是不可能的,所以graavm提供一个agent工具,该工具会生成整个代码中需要用到反射的配置文件,但前提是,需要你把项目打成jar包....生成配置文件之后,再编译成二进制。
好了,编译不成功遇到问题可以来群里找我 626070845,接下来,开干
实战
pom
<?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>native-netty-log4j</artifactId> <dependencies> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.0.M3</version> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.75.Final</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.5</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.12</version> </dependency> <dependency> <groupId>com.ibeetl</groupId> <artifactId>beetl</artifactId> <version>3.10.0.RELEASE</version> </dependency> </dependencies> <build> <finalName>native-image-js</finalName> <plugins> <!-- <plugin>--> <!-- <groupId>org.apache.maven.plugins</groupId>--> <!-- <artifactId>maven-shade-plugin</artifactId>--> <!-- <version>3.2.4</version>--> <!-- <executions>--> <!-- <execution>--> <!-- <id>package-jar</id>--> <!-- <phase>package</phase>--> <!-- <goals>--> <!-- <goal>shade</goal>--> <!-- </goals>--> <!-- <configuration>--> <!-- <transformers>--> <!-- <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">--> <!-- <mainClass>com.lang.Application</mainClass>--> <!-- </transformer>--> <!-- </transformers>--> <!-- </configuration>--> <!-- </execution>--> <!-- </executions>--> <!-- </plugin>--> <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 --initialize-at-build-time=org.apache.log4j.PatternLayout --initialize-at-build-time=org.apache.log4j.Layout --initialize-at-build-time=org.slf4j.MDC --initialize-at-build-time=org.slf4j.LoggerFactory --initialize-at-build-time=org.slf4j.impl.StaticLoggerBinder --initialize-at-build-time=org.apache.log4j.helpers.Loader --initialize-at-build-time=org.apache.log4j.Logger --initialize-at-build-time=org.apache.log4j.helpers.LogLog --initialize-at-build-time=org.apache.log4j.LogManager --initialize-at-build-time=org.apache.log4j.spi.LoggingEvent --initialize-at-build-time=org.slf4j.impl.Log4jLoggerFactory --initialize-at-build-time=org.slf4j.impl.Log4jLoggerAdapter --initialize-at-build-time=com.lang.server.handler.FarChannelHandler --initialize-at-build-time=java.beans.Introspector --initialize-at-build-time=com.sun.beans.introspect.ClassInfo --initialize-at-run-time=io.netty.channel.epoll.Epoll --initialize-at-run-time=io.netty.channel.epoll.Native --initialize-at-run-time=io.netty.channel.epoll.EpollEventLoop --initialize-at-run-time=io.netty.channel.epoll.EpollEventArray --initialize-at-run-time=io.netty.channel.DefaultFileRegion --initialize-at-run-time=io.netty.channel.kqueue.KQueueEventArray --initialize-at-run-time=io.netty.channel.kqueue.KQueveEventLoop --initialize-at-run-time=io.netty.channel.kqueue.Native --initialize-at-run-time=io.netty.channel.unix.Errors --initialize-at-run-time=io.netty.channel.unix.1ovArray --initialize-at-run-time=io.netty.channel.unix.Limits --initialize-at-run-time=io.netty.util.internal.logging.Log4JLogger --initialize-at-run-time=io.netty.channel.unix.Socket --initialize-at-run-time=io.netty.channel.ChannelHandlerMask --report-unsupported-elements-at-runtime --allow-incomplete-classpath --enable-url-protocols=http -H:+ReportExceptionStackTraces -H:EnableURLProtocols=http -H:EnableURLProtocols=https <!-- -H:ReflectionConfigurationFiles=E:\AAAA_CODE\new-eclipse-workspace\native-netty-log4j\reflect-config.json--> <!-- 新增--> <!--trace 表示编译时 进行 跟踪,有些情况下可能会报错,比如在这里设置了A类,但是A类没有MAIN方法 会导致报错--> <!-- -trace-class-initialization=org.apache.log4j.PatternLayout--> --trace-class-initialization=org.apache.log4j.Layout --trace-class-initialization=java.beans.Introspector --trace-class-initialization=com.sun.beans.introspect.ClassInfo -Dio.netty.tryReflectionSetAccessible=true --add-exports=java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED <!-- -language:js--> </buildArgs> </configuration> <executions> <execution> <goals> <goal>native-image</goal> </goals> <phase>package</phase> </execution> </executions> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.0.0</version> <executions> <execution> <id>java-agent</id> <goals> <goal>exec</goal> </goals> <configuration> <executable>java</executable> <workingDirectory>${project.build.directory}</workingDirectory> <arguments> <argument>-classpath</argument> <classpath/> <argument>com.lang.Application</argument> </arguments> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
上面注释掉的plug是用于生成jar的,所以生成jar时,需要把下面编译原生的plug注释掉,把生成jar的plug放开
直接idea上点击maven packeage 生成jar包
生成反射配置文件(注意配置好javahome和graavm)
不需要使用ms的控制台编译工具
./java -agentlib:native-image-agent=config-output-dir=E:\AAAA_CODE\new-eclipse-workspace\native-netty-log4j\conf -jar E:\AAAA_CODE\new-eclipse-workspace\native-netty-log4j\target\native-image-js.jar
- config-output-dir 指定反射配置文件输出的目录
- 可以看到,上面的指令执行后,jar会被执行一次,以便vm获取到反射信息
conf目录下也生成了反射配置文件
maven项目中增加反射文件
在reource目录下增加META-INF/native-image 目录,将之前conf下的所有文件复制到此处
生成二进制
先把pom中生成jar的plug注释掉,打开生成二进制的plug
使用ms编译工具进入到项目根目录
执行 mvn -Pnative clean package
-
生成二进制成功,可以看到还生成了相关需要的dll文件
-
执行exe,启动速度非常快
注意:由于程序没有写死循环,所以执行完就退出控制台,可以先开一个控制台,再把exe拖到这个控制台执行就行了,否则你需要在程序中写个死循环,防止程序执行完就关掉
执行mvn -Pnative clean package 遇到的问题
- 我遇到了万恶的
should not reach here
,但是也能正常生成EXE,先不管它就好。以后解决
- 注意 由于反射时,需要用到不同的类,如果你的项目在编译二进制时 出现以下的报错提示
--initialize-at-build-time=java.beans.Introspector
--initialize-at-build-time 是指,在编译时 需要找这样的类,你只需要加到pom中即可
这篇关于graalvm 编译原生java 解决反射的问题 maven配置的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-27OpenFeign服务间调用学习入门
- 2024-12-27OpenFeign服务间调用学习入门
- 2024-12-27OpenFeign学习入门:轻松掌握微服务通信
- 2024-12-27OpenFeign学习入门:轻松掌握微服务间的HTTP请求
- 2024-12-27JDK17新特性学习入门:简洁教程带你轻松上手
- 2024-12-27JMeter传递token学习入门教程
- 2024-12-27JMeter压测学习入门指南
- 2024-12-27JWT单点登录学习入门指南
- 2024-12-27JWT单点登录原理学习入门
- 2024-12-27JWT单点登录原理学习入门