版本冲突,鱼和熊掌不能兼得?

弱水三千只取一瓢

不同模块依赖相同的jar 但是jar的version不同。
jvm里面的类加载器是双亲委派模式,一个类只需要在双亲委派模式下正常加载过(唯一全限定名:包名+类名)一次,就不会重复加载。故多个版本的jar只有一个会被加载。
那么未被加载的jar没有存在的意义且会增加不必要的麻烦,maven在处理这类(不同version的jar中只保留一个)冲突时,遵循两种规则:最短路径优先、最先声明优先。基于上述规则使得不同version的jar只会保留一个。
但是基于maven的默认规则确定的jar可能不是我们想要的,从而导致 NoSuchMethodError ClassNotFoundException 问题的出现。为解决这类问题,我们常采用的方式有两种:

  • 对特定模块进行 exclude 。
  • 在父pom中使用 dependencyManagement 指定版本。

    小孩子才作选择,我都要

    image.png
    如图所示的一种场景,新版本中的类中删除了之前版本中的一个methodA,新增了一个methodC ,删除的methodA正好被其中一个模块所依赖,新增的methodC被另一个模块依赖。这种情况下我们无法单纯的通过排除多余的jar来解决问题,此时两个版本都要保留。
    JVM类加载器只会加载某个类一次,是通过全路径的包名+类名来区分做到的,我们要想加载不同版本的同一个类,有两种简单的方式,第一种改类名,第二种改包名 。修改类名的方式影响面比较大,故修改包名较为合适。
    基于上述原理maven为解决这一问题提供了一个插件: maven-shade-plugin

    团队开发依赖项代码在动态变化?

    【大漂亮】开发的项目需要依赖【大聪明】开发的一个X.jar。两边同时开发,X.jar中不断的增加功能。【大聪明】每开发一个新功能就将jar deploy到公司私服。【大漂亮】郁闷得一逼,由于maven的缓存机制,要调用【大聪明】X.jar中开发的新功能,每次都需要先手动删除本地maven仓库中缓存的X.jar。
    解决方案: 只有以-SNAPSHOT结尾的版本号会被Maven视为开发版本,开发版本每次都会重复下载,