SpringBoot第三方jar包问题处理记录

2019-04-25  本文已影响0人  Tayle

SpringBoot第三方jar包问题处理记录

问题描述

​ SpringBoot项目使用到了本地签名过xxx.jar包,使用spring-boot-maven-plugin常规打包后通过java命令执行jar包会出现异常。
\color{#ea4335}{ java.lang.SecurityException: JCE cannot authenticate the provider BC}
​ 直接使用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

按照以上操作办法处理后,依旧出现\color{#ea4335}{ java.lang.SecurityException: JCE cannot authenticate the provider BC}

结合异常出现的情况,初步断定是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目录下,方便于版本更新操作。

上一篇下一篇

猜你喜欢

热点阅读