Maven如何处理第三方依赖A、B依赖同一Jar不同版本的冲突
类加载隔离/包重命名
用Maven Shade、Gradle Shadow这类构建工具,把A依赖的C 1.0进行包路径重命名(比如把com.example.c改成com.example.c.v1),再和A打包成独立Jar。这样A调用的是重命名后的C 1.0类,和B依赖的C 2.0类完全隔离,不会出现类路径冲突。也可以自定义类加载器,为A和C 1.0单独创建类加载上下文,避开和B的类加载环境干扰。兼容层适配
强制项目全局引入C 2.0,排除A对C 1.0的依赖,然后手动实现C 1.0中A用到但C 2.0已变更的API。比如C 1.0的C.oldMethod()在C 2.0中被移除,就写一个和原C类同名同包的类,在里面实现oldMethod()并调用C 2.0的新API。这种方式只适合A用到的C 1.0 API较少的场景,不然开发成本太高。模块化拆分
把项目拆成两个独立模块:一个模块只引入A和C 1.0,封装好对外的服务接口;另一个模块引入B和C 2.0。两个模块通过HTTP、RPC这类进程间通信方式或者消息队列交互,彻底避免同一个JVM里出现版本冲突。应急修改第三方Jar(不推荐)
解压A的Jar包,把C 1.0的类直接打包进A的Jar里,同时删除A的依赖声明文件里对C的引用。这样A运行时会优先加载自身Jar内的C 1.0类,B则用类路径里的C 2.0。但这个方案维护成本高,后续升级A或C都得重新处理,还可能违反开源协议,只能当临时应急用。优先兼容一方版本(视情况)
先验证B能不能兼容C 1.0,如果可行,直接在构建工具的依赖管理里强制全局用C 1.0。这是成本最低的方案,但必须做好充分测试,防止B出现功能异常。
内容的提问来源于stack exchange,提问作者Jason

