maven解決項目沖突
在開發我們都會用maven來管理項目jar包,非常方便。但是,有時候會出現jar沖突的情況,導致項目起不來,這個時候我們就得去排查哪些jar包沖突了。
在jar沖突的時候,會報java.lang.SecurityException: class "xxxxxxx"'s signer information does not match signer information of other classes in the same package的錯誤
比如說:
Thread[main,5,main] exit with uncaught error java.lang.SecurityException: class "javax.servlet.FilterRegistration"'s signer information does not match signer information of other classes in the same package
java.lang.SecurityException: class "javax.servlet.FilterRegistration"'s signer information does not match signer information of other classes in the same package
at java.lang.ClassLoader.checkCerts(ClassLoader.java:895)
at java.lang.ClassLoader.preDefineClass(ClassLoader.java:665)
at java.lang.ClassLoader.defineClass(ClassLoader.java:758)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
signer information does not match signer information of other classes in the same package說明了不同版本jar包中有相同類,並且類實現有沖突,無法兼容。
可以在idea中通過快捷鍵ctrl+N查看沖突的類,如果起沖突的話,肯定會有復數相同名字的類,查看這些類分別屬於哪些jar包,用於后面排查。
解決jar包沖突,首先一定會去查看pom文件,看看有沒有重復導入版本沖突的依賴。很多時候,雖然pom沒問題,沒有沖突,但是由於有一些依賴間接引用了其它版本的相關依賴,這也會導致jar出現沖突。
我們可以通過查詢maven的依賴樹來查看具體沖突的jar包,如果配置了maven環境變量的話,在終端中輸入mvn dependency:tree,如果沒有配置環境變量,可以在idea的maven命令行窗口輸入。
如果servlet的jar包沖突了,就用ctrl+f查詢有哪些依賴間接引用了servlet依賴
下面是資產樹的輸出例子:
[INFO] +- org.apache.httpcomponents:httpclient:jar:4.2.3:compile
[INFO] +- org.apache.httpcomponents:httpcore:jar:4.2.1:compile
[INFO] +- org.eclipse.jetty.aggregate:jetty-all-server:jar:8.1.15.v20140411:compile
[INFO] | +- org.eclipse.jetty.orbit:javax.servlet:jar:3.0.0.v201112011016:compile
[INFO] | +- org.eclipse.jetty.orbit:javax.security.auth.message:jar:1.0.0.v201108011116:compile
[INFO] | +- org.eclipse.jetty.orbit:javax.mail.glassfish:jar:1.4.1.v201005082020:compile
[INFO] | +- org.eclipse.jetty.orbit:javax.activation:jar:1.1.0.v201105071233:compile
[INFO] | \- org.eclipse.jetty.orbit:javax.annotation:jar:1.1.0.v201108011116:compile
[INFO] +- com.jcraft:jsch:jar:0.1.44:compile
使用mvn dependency:tree > x.txt命令可以將依賴樹輸出到文本中,更容易進行分析
依賴樹中最外層根代表父依賴,父依賴下面每一個+-號代表這個父依賴的子依賴,\-符號代表同輩分依賴中的最后一個,可以簡單理解為同一組依賴中的最后一個依賴,作為一個分界線。
以上面的例子為例,在依賴中查看哪些依賴間接引用了沖突的依賴,比如說hadoop-common引用了servlet依賴,版本和我們自己導入的servlet依賴沖突了,那么為了解決沖突,我們需要把hadoop-common依賴的子依賴排除掉。
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
可以通過exclusion標簽將子依賴排除掉。排除掉所有沖突的子依賴之后,刷新一下maven,然后重新編譯項目,檢查idea項目的Libraries目錄下是否還有沖突依賴,如果沒有的話,那么項目應該可成功運行了。