通过以上文章, 大致能理解和解决Maven依赖冲突的问题, 但是这里存在一个隐式的问题, 而且问题还依据不同的平台可能还有不同的表现
例如示例中的类 SimpleTransformer 如果直接运行就会抛异常 ExceptionInInitializerError
在多线程环境里, 会引发接下来的引用该类的客户端代码抛异常 ClassNoDefFoundError
由于日志平台最近有点问题, 导致了第一个异常被掩盖住了, 看到的只有 ClassNoDefFoundError
, 一眼看过去并没有看到问题, 而且使用 Maven Helper 插件查看依赖冲突也没发现问题, 直到在依赖树中搜索 asm 发现有两个 asm 版本依赖共存
因为 两个 asm 依赖的 groupId 不一致, 虽然当中的类的结构大多一致, 包名一致 此时就有可能导致运行时错误
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>5.1</version>
</dependency>
以上示例中报错的根源是 org.objectweb.asm.ClassVisitor
类在 3.1 版本中是一个接口, 而到了 5.1 已经变成了抽象类, 于是两个依赖都被package了, 如果是war包这样的依赖, 还会进行解压, 此时又涉及类加载器的规则, 在不同的平台上可能有不同的表现, 也就有了更坑的可能性
还有此类问题还有 commons-io netty 等三方库, 都有变更 groupId 和 artifactId 的历史, 神坑…
此外 如果项目是Maven多模块的项目,例如分为 web service 等模块,如果子模块之间出现了一些 限定名一致的类也会引发该问题,但是同样的在IDEA中能正确编译和运行,当打包后才会暴露问题