欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > 同时使用两个版本的jar、jar包冲突共存

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

2025/2/23 1:17:58 来源:https://blog.csdn.net/weixin_48835367/article/details/144362952  浏览:    关键词:同时使用两个版本的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包共存

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词