背景
通过maven的GAV完全可以避免同一个构件在项目中使用===》也就是打包出来最终同一个GA的构件一定只有一个
但是除了这种GA构件唯一 我们在java项目中还经常碰到class完全相同的场景 比如典型的就是mail
像这种构件名称不一样导致出现class重复的问题也不再少数
对于这种问题怎么解决呢???
对策
其实说难不难 说易不易~我们需要做的是将对应的class进行check下是否存在重复即可!
抽象说来 就是说一堆文件夹中我们要找到文件路径完全相同的文件
方案1
将所有的jar遍历里面的class文件进行输出后排序 发现有重复就输出~
比如我们可以一些第三方脚本show-duplicate-java-classes
在对应目录执行后输出如下
11 (1@3): ./woden-impl-dom-1.0M8.jar ./stax-api-1.0.1.jar ./xml-apis-1.3.04.jar
1 javax/xml/namespace/QName.class
12 (223@2): ./quartz-all-1.6.1.jar ./quartz-1.6.1.jar
1 org/quartz/impl/jdbcjobstore/JobStoreSupport$VoidTransactionCallback.class
2 org/quartz/impl/jdbcjobstore/JobStoreSupport$25.class
3 org/quartz/impl/StdJobRunShellFactory.class
4 org/quartz/impl/QuartzServer.class
这样的话完全可以根据对应的问题进行修正
方案2
使用maven插件在编译期就发现问题【当然会忽略一些容器提供的jar】 但是绝大部分是OK的 比如如下
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce-ban-duplicate-classes</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<banDuplicateClasses>
<ignoreClasses>
<ignoreClass>javax.*</ignoreClass>
<ignoreClass>org.junit.*</ignoreClass>
<ingoreClass>org.aspectj.*</ingoreClass>
<ingoreClass>org.jboss.netty.*</ingoreClass>
<ingoreClass>org.apache.juli.*</ingoreClass>
<ingoreClass>org.apache.commons.logging.*</ingoreClass>
<ingoreClass>org.apache.log4j.*</ingoreClass>
<ingoreClass>org.objectweb.asm.*</ingoreClass>
<ingoreClass>org.parboiled.*</ingoreClass>
<ingoreClass>org.apache.xmlbeans.xml.stream.*</ingoreClass>
<ingoreClass>org.json.JSONString</ingoreClass>
</ignoreClasses>
<findAllDuplicates>true</findAllDuplicates>
</banDuplicateClasses>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>extra-enforcer-rules</artifactId>
<version>1.0-beta-6</version>
</dependency>
</dependencies>
</plugin>
比如某位同学引入了新的依赖导致系统中出现了一些新的class和原先重复了 那么在maven编译的过程中就会报错
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-enforcer-plugin:1.4.1:enforce (enforce-ban-duplicate-classes) on project web: Some Enforcer rules have failed. Look above for specific messages explaining why the rule failed. -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR] mvn <goals> -rf :web
可以查看到详细的报错信息
[INFO] --- maven-enforcer-plugin:1.4.1:enforce (enforce-ban-duplicate-classes) @ web ---
[INFO] Adding ignore: javax.*
[INFO] Adding ignore: org.junit.*
[INFO] Adding ignore: org.aspectj.*
[INFO] Adding ignore: org.jboss.netty.*
[INFO] Adding ignore: org.apache.juli.*
[INFO] Adding ignore: org.apache.commons.logging.*
[INFO] Adding ignore: org.apache.log4j.*
[INFO] Adding ignore: org.objectweb.asm.*
[INFO] Adding ignore: org.parboiled.*
[INFO] Adding ignore: org.apache.xmlbeans.xml.stream.*
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.BanDuplicateClasses failed with message:
Duplicate classes found:
Found in:
org.skyscreamer:jsonassert:jar:1.4.0:compile
org.json:json:jar:20140107:compile
Duplicate classes:
org/json/JSONString.class
我们可以知道org.json.JSONString这个类在两个jar中都出现了~需要注意!