SpringBoot第三方jar包问题处理记录
问题描述
SpringBoot项目使用到了本地签名过xxx.jar包,使用spring-boot-maven-plugin常规打包后通过java命令执行jar包会出现异常。
直接使用sts启动服务一切正常。
问题分析
SecurityException
从异常信息来看,JCE无法正常验证,通过查看异常堆栈信息发现是由第一个第三方jar包抛出。
看到这个异常之前未接触过,果断寻求广大大佬们的求助。搜索异常信息,发现很多大佬们的解决方法是
1、在\jre1.8.0_131\lib\security这个文件里找到‘java.security’,添加security.provider.x=org.bouncycastle.jce.provider.BouncyCastleProvider
2、在\jre1.8.0_131\lib\ext这个文件夹里添加两个jar包:bcprov-jdk15-135.jar 和bcprov-jdk16-143.jar
按照以上操作办法处理后,依旧出现
结合异常出现的情况,初步断定是jar包的引用有问题。怀疑是第三方的jar包在打包的时候遭到了破坏。
启动包检查
顺着这一思路继续分析spring-boot-maven-plugin的打包原理。解压打包后的jar包发现项目依赖的jar包都被打包在BOOT-INF\lib目录下。本地的jar包也被打包进去了。当时pom.xml配置的打包插件配件如下
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
<layout>ZIP</layout>
<minimizeJar>true</minimizeJar>
</configuration>
</plugin>
通过手动删除lib目录下的签名xxx.jar包,在项目同级目录创建lib目录,将xxx.jar存放在lib目录,启动时通过参数-Dloader.path
指向了外置目录,告诉SpringBoot允许从外部加载依赖,启动后发现问题解决。
解决办法
通过以上尝试得知关键问题在于SpringBoot打包本地依赖jar的时候会破坏本地签名过的xxx.jar包。根据此原因,整体项目打包配置修改如下:
本地jar包引入
<!-- 引用本地jar包 -->
<dependency>
<groupId>com.chenz</groupId>
<artifactId>chenz</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/xxxx.jar</systemPath>
</dependency>
使用maven-jar-plugin插件打jar包
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix><!-- 系统会将这个路径下所有的jar包加入到classpath路径中-->
<useUniqueVersions>false</useUniqueVersions>
<mainClass>com.xxx.xxx.xxxApplication</mainClass>
</manifest>
<manifestEntries>
<Class-Path>./</Class-Path><!--系统会将这个路径加入到classpath中,主要是用于加载配置文件-->
</manifestEntries>
</archive>
<excludes><!--排除不需要打入jar包里的配置 -->
<exclude>lib/</exclude>
<exclude>config/**.cer</exclude>
<exclude>**-dev.yml</exclude>
</excludes>
</configuration>
</plugin>
<!--maven-dependency-plugin 复制依赖jar包到指定目录-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includes>
<!-- 设置不包含任何jar包 交由maven-jar-plugin压缩本项目class-->
<include>
<groupId>nothing</groupId>
<artifactId>nothing</artifactId>
</include>
</includes>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
<layout>ZIP</layout>
<minimizeJar>true</minimizeJar>
</configuration>
</plugin>
以上可通过自定义打包策略解决问题,同时将依赖的其他jar包全部从项目本身的jar包中抽离出来放到lib目录下,方便于版本更新操作。
网友评论