自学内容网 自学内容网

同时使用两个版本的jar、jar包冲突共存

springboot项目如果遇到第三方jar包冲突,报错java.lang.ClassNotFoundException异常等

情况1,项目中直接引用了两个版本的第三方jar包

对于这种情况,是很好解决的。例如,项目中已经导入了xxx.v1.jar第三方包。现在新功能要求使用xxx.v2.jar第三方包,并且需要保持原来的v1包不动。
我们可以对v2这个jar包的包名重新命名,例如原来是cn.alibaba.XXX格式的包,改成cn.v2.alibaba.XXX包名。项目中使用的时候,import使用cn.v2.alibaba.XXX包即可。
使用maven插件即可实现这个功能maven-shade-plugin

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.4.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <relocations>
                            <relocation>
                                <pattern>com.example.some.library</pattern>
                                <shadedPattern>com.example.shaded.some.library</shadedPattern>
                            </relocation>
                        </relocations>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

情况2,项目中两个第三方jar包中引用了两个版本的第三方jar包

例如项目中引用了一个阿里的jar包ali.jar,这个jar包内部又引用了xxx.v1.jar第三方包。
同时项目中也引用了华为的jar包hua.jar,这个jar包内部又引用了xxx.v2.jar第三方包。
因为冲突的包是两个第三方包导致的,我们改不了他们的代码,上面第一种方式不能用了。
sofa-ark方式:
使用https://www.sofastack.tech/projects/sofa-boot/sofa-ark-spring-boot-demo/

原理

原理是利用不同的classLoader之间类是隔离的,框架大概是有一个base服务端jar包,然后自己的业务代码jar包1(其中包含阿里的jar包引用),另一个自己的业务代码jar包2(其中包含华为的jar包引用)。
这样就生成了3个jar包,先启动base服务端jar包,然后剩下的两个业务代码包添加到base服务端。
这种方式比较于其他框架来说,是比较轻量的,但是改了项目结构,还有未知bug。不是很推荐。还是建议手动处理一下冲突的jar包,升级jar包版本,或者使用其他方式。

demo

参考我自己的demo:
git@github.com:shenshuxin01/sofa-ark-guides.git

SOFAArk 工程用例
.
│
├── mina-v1-demo(业务环境1)
│ 
└── mina-v2-demo(业务环境2)
│ 
└── start-demo(基础环境)
快速开始

执行mvn clean package生成jar

start-demo

启动项目先启动这个start-demo,会看到启动日志

16:16:37.093 [SOFA-ARK-telnet-server-worker-0-T1] INFO io.netty.handler.logging.LoggingHandler -- [id: 0x6f1ce4f0] BIND: 0.0.0.0/0.0.0.0:1234
Ark container started in 956 ms.
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.3.0)

sofaark监听1234端口

mina-v1-demo

这个是业务环境1,引用了mina1版本的依赖包,包含类org.apache.mina.common.IoFilter 注意这个类是1版本的jar包才有的,
找到对应的jar包mina-v1-demo-1.0-SNAPSHOT-ark-biz.jar
打开telnet 连接1234端口,执行biz -i file:///D:\sofa-ark-fork\mina-v1-demo\target\mina-v1-demo-1.0-SNAPSHOT-ark-biz.jar
看控制台会输出

mina-v2-demo

这个是业务环境2,引用了mina2版本的依赖包,包含类org.apache.mina.core.filterchain.IoFilter 注意这个类是2版本的jar包才有的,
找到对应的jar包mina-v2-demo-1.0-SNAPSHOT-ark-biz.jar
打开telnet 连接1234端口,执行biz -i file:///D:\sofa-ark-fork\mina-v2-demo\target\mina-v2-demo-1.0-SNAPSHOT-ark-biz.jar
看控制台会输出

这样就会同时运行2个版本的jar包了,但是这个对版本依赖有要求,使用jdk8和springboot2.6.6版本的是官网的示例,我自己使用的是
jdk使用21
maven使用3.9
Spring Boot v3.3.0

官网地址

https://www.sofastack.tech/projects/sofa-boot/sofa-ark-spring-boot-demo/

备注

看了几天其他的解决方法,并没有合适的方案,都是要重构项目架构,通过classLoader实现冲突jar包共存。
我看springboot的启动过程中可以指定classLoader,或许可以实例化某个bean的时候设置自定义的classLoader,实现jar包共存


原文地址:https://blog.csdn.net/weixin_48835367/article/details/144362952

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!