微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

  • 可以看到,上面的指令执行后,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中即可

原文地址:https://www.cnblogs.com/cfas/p/16339789.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


前言 此种方式已过时,不再推荐,当下推荐方式:自我救赎 → 利用 IDEA 和 Spring Boot 搭建 SSM 本文旨在利用maven搭建ssm环境,而关于maven的具体内容,大家可以去阅读《Maven 实战》。其实园内这方面文章已有不少,那么为什么我还要重复造轮子呢?我只是想记录自己的实践
前言 项目中用到了maven,而且用到的内容不像利用maven/eclipse搭建ssm(spring+spring mvc+mybatis)用的那么简单 maven的核心是 pom.xml,那么我们就来看看那些不同的地方 给我印象最深的就是如下四个元素:modules、parent、propert
开心一刻 今天去幼儿园接小侄女,路上聊起了天 小侄女:小叔,今天我吃东西被老师发现了 我:老师说了什么 小侄女:她说拿出来,跟小朋友一起分享 我:那你拿出来了吗 小侄女一脸可怜的看向我,说道:没有,我没有那么多鼻屎 SPI 概念 SPI 全称&#160;Service Provider Interf
本篇文章和大家了解一下怎么搭建maven私有仓库。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。在本篇文章中,我们将介绍如何搭建一个Maven...
今天小编给大家分享的是如何解决Maven依赖冲突,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。目...
这篇文章主要介绍了Maven仓库分类的优先级是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Maven仓库分类的优先级是什么文...
本篇内容主要讲解“Maven怎么实现自己的starter依赖”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Maven怎
本篇内容主要讲解“maven不能下载oraclejdbc驱动的问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大...
这篇文章主要介绍了怎么使用maven基本命令打包包名的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么使用maven基本命令打包包...
本篇内容介绍了“maven中profile如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧...