Jar动态编译找不到包的解决方案
最近写程序遇到需要动态编译代码的需求,主要思路是扫描、生成代码、编译成class、生成实例,注入静态容器里。
扫描、生成代码、编译成class、生成实例、注入容器都是Java基础,这里没有多少讲解的必要。主要是项目打包以后,部署到正式环境时,遇到了无法动态编译的问题。
问题描述
项目默认使用spring-boot-maven-plugin来打包,打包出来的jar包使用java -jar来运行,无法找到符号,截图
![在这里插入图片描述](https://img-blog.csdnimg.cn/ba39a9de6ce14e18af7729cc0259ea2b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATlVDLTE5MDc=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
排查思路:
1.我们首先怀疑相关依赖是否导入到jar包,我们解压jar文件,在BOOT-INF\lib里面发现需要的jar已存在
2.既然jar已存在,我们需要怀疑导入的jar与开发的jar是否一致,因为开发时用到了另一个项目生成的jar,可能本地仓库的jar与实际开发的jar不一致。将依赖的jar重新编译,重新编译项目,发现故障依然没有解决。
3.使用源码启动程序,一切正常,打包后启动,无法启动。在IDE中启动与jar包启动的区别是classpath存在不同
,因此我们知道需要解决classpath问题。
解决方案:
网上有解决方案,将jar扫描一遍,获取流来获取目标class然后调用compiler,但是这存在很强的侵入性,不优先考虑。
我们去掉spring-boot-maven-plugin
来编译程序,去除依赖项,获得本项目的jar包,再将使用spring-boot-maven-plugin打包后的jar包中的BOOT-INF\lib里面的jar包导入到相同路径
·,对源码jar包与依赖jar包进行打包,添加主程序清单,运行,发现可行。
其他:
Maven打jar包时设置入口:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.main.Application</mainClass> <!-- 此处为主入口-->
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>