1. 问题描述
-
一些开源的Java项目对依赖有着很严格的要求,会在root模块的pom.xml文件中,使用各种maven plugin检查依赖是否规范
- apache的
maven-dependency-plugin
:可以检查是否存在unused dependency、used但未explicitly import的dependency等 org.basepom.maven
的duplicate-finder-maven-plugin
:可以查找和标记Java clapss上重复和冲突的class或resource
- apache的
-
最近的工作中,就因为引入新的依赖导致
duplicate-finder-maven-plugin
的检查未通过,关键信息如下 -
仔细研读后,总结起来就是
duplicate-finder-maven-plugin
的检查不通过(虽然是WARNING信息)- 在complile、runtime、test classpath,都发现了 重复但相同的资源
char-whitelist.yaml
,这个资源文件来自两个不同的依赖com.xxx.apm:config-loader:1.0.10
、com.xxx.metrics2:core:1.1.2
- 在complile、runtime、test classpath,都发现了重复但不同的类
com.xxx.apm.shade.jnr.unixsocket.UnixSeqPacketChannel
,这个资源文件来自两个不同的依赖com.xxx.metrics2:extension-exporter-unix-socket:1.1.2
、com.xxx:metrics4j:1.0.57
java[INFO] --- duplicate-finder-maven-plugin:1.5.1:check (default) @ onequery-common --- [INFO] Checking compile classpath [INFO] Checking runtime classpath [INFO] Checking test classpath [WARNING] Found duplicate (but equal) resources in [com.xxx.apm:config-loader:1.0.10, com.xxx.metrics2:core:1.1.2]: [WARNING] char-whitelist.yaml [WARNING] Found duplicate and different classes in [com.xxx.metrics2:extension-exporter-unix-socket:1.1.2, com.xxx:metrics4j:1.0.57]: [WARNING] com.xxx.apm.shade.jnr.unixsocket.UnixSeqPacketChannel [WARNING] Found duplicate classes/resources in compile classpath. [WARNING] Found duplicate (but equal) resources in [com.xxx.apm:config-loader:1.0.10, com.xxx.metrics2:core:1.1.2]: [WARNING] char-whitelist.yaml [WARNING] Found duplicate and different classes in [com.xxx.metrics2:extension-exporter-unix-socket:1.1.2, com.xxx:metrics4j:1.0.57]: [WARNING] com.xxx.apm.shade.jnr.unixsocket.UnixSeqPacketChannel [WARNING] Found duplicate classes/resources in runtime classpath. [WARNING] Found duplicate (but equal) resources in [com.xxx.apm:config-loader:1.0.10, com.xxx.metrics2:core:1.1.2]: [WARNING] char-whitelist.yaml [WARNING] Found duplicate and different classes in [com.xxx.metrics2:extension-exporter-unix-socket:1.1.2, com.xxx:metrics4j:1.0.57]: [WARNING] com.xxx.apm.shade.jnr.unixsocket.UnixSeqPacketChannel [WARNING] Found duplicate classes/resources in test classpath.
- 在complile、runtime、test classpath,都发现了 重复但相同的资源
-
按照之前暴力求解的方法,直接找到对应的依赖,从其所在的直接依赖中exclude掉任意一个就行
-
结果,打包部署后发现服务无法运行,这时候只能静下心来研究
duplicate-finder-maven-plugin
2. 解决办法
- 官方文档:duplicate-finder-maven-plugin,github:basepom/duplicate-finder-maven-plugin
- 官方文档内容很多,看得人心浮气躁,从github上发现了这个插件的源分支: Ning maven-duplicate-finder This plugin is a friendly fork (same main authors) of the Ning maven-duplicate-finder plugin. It is configuration compatible to the ning plugin; the only change required is the group and artifact id of the plugin itself.
Ning maven-duplicate-finder
的REAME非常友好,很适合新手,这里列举一些简单的使用方式
2.1 完全跳过对某些依赖的check
-
在极少数情况下,需要完全跳过对某个依赖的check,这时可以使用
<ignoredDependencies>
标签(请在绝对必要时使用该标签
)xml<plugin> <groupId>com.ning.maven.plugins</groupId> <artifactId>duplicate-finder-maven-plugin</artifactId> <version>1.1.0</version> <configuration> <ignoredDependencies> <dependency> <groupId>xml-apis</groupId> <artifactId>xml-apis</artifactId> <version>1.3.02</version> </dependency> </ignoredDependencies> ... </configuration> </plugin>
2.2 跳过对依赖中某些类或资源的check
-
一般冲突的是多个依赖中的重名类或资源,这时可以
- 使用
<conflictingDependencies>
标签,指明冲突的依赖 - 使用
<classes>
标签,指明可以跳过重复类 - 使用
<packages>
标签,指明可以跳过的重复类的包名 - 使用
<resources>
标签,指明可以跳过的重复资源 - 使用
<resourcePattern>
标签,指明可以跳过的重复资源的正则表达式
xml<plugin> <groupId>com.ning.maven.plugins</groupId> <artifactId>duplicate-finder-maven-plugin</artifactId> <version>1.1.0</version> <configuration> <exceptions> <exception> <conflictingDependencies> <dependency> <groupId>jaxen</groupId> <artifactId>jaxen</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>xml-apis</groupId> <artifactId>xml-apis</artifactId> <version>[1.3.02,1.3.03]</version> </dependency> </conflictingDependencies> <classes> <class>org.w3c.dom.UserDataHandler</class> </classes> <packages> <package>org.w3c.dom.ls</package> </packages> <resources> <resource>log4j.xml</resource> </resources> <resourcePatterns> <resourcePattern>files.*</resourcePattern> </resourcePatterns> </exception> </exceptions> </configuration> </plugin>
- 使用
2.3 其他配置,如跳过duplicate检查
-
文章开头的duplicate信息是WARNING级别,但maven编译也失败了,这是因为
<failBuildInCaseOfConflict>
为true,一旦遇到冲突就失败 -
如果想偷懒,可以通过调整下面的配置项,使整个项目不进行check、跳过某些classpath的check、甚至在出现冲突时编译不失败等
-
更多配置可以参考:Simple configuration
xml<skip>false</skip> <checkCompileClasspath>true</checkCompileClasspath> <checkRuntimeClasspath>true</checkRuntimeClasspath> <checkTestClasspath>true</checkTestClasspath> <failBuildInCaseOfDifferentContentConflict>false</failBuildInCaseOfDifferentContentConflict> <failBuildInCaseOfEqualContentConflict>false</failBuildInCaseOfEqualContentConflict> <failBuildInCaseOfConflict>false</failBuildInCaseOfConflict>