天天看點

【Maven】--如何解決包沖突

1、常見包沖突異常

2、包沖突産生的原因

3、如何解決包沖突

3.1首先要找到沖突的包

3.2 解決包沖突

1、常見包沖突異常

Caused by: java.lang.NoSuchMethodError
Caused by: java.lang.ClassNotFoundException
Caused by: java.lang.NoClassDefFoundError
Caused by: java.lang.LinkageError      

2、包沖突産生的原因

主要考慮 Maven 依賴傳遞原則,在編譯時,編譯器會選擇低版本的依賴打入 jar 中。

(1)最短路徑優先原則

Maven 面對 D1 和 D2 時,會預設選擇最短路徑的那個 jar 包,即 D2。

E->F->D2 比 A->B->C->D1 路徑短 1個      

(2)最先聲明優先原則

如果路徑一樣,比如:A->B->C1, E->F->C2 ,兩個依賴路徑長度都是 2,那麼會選擇最先聲明的 C1      

3、如何解決包沖突

3.1 找到沖突的包

方法一:先在插件中安裝 Maven Helper,再使用 Maven Helper 插件,如下

【Maven】--如何解決包沖突

方法二:cd 到項目目錄下,然後使用 mvn 指令(mvn dependency:tree)

【Maven】--如何解決包沖突

3.2 解決包沖突

方法一:在 pom.xml 中,使用 exclusion 排除定位到的沖突包。

<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-java</artifactId>
    <version>${apache.flink.version}</version>
    <exclusions>
        <exclusion>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </exclusion>
    </exclusions>
</dependency>      

方法二:引入高版本的 jar 包,使用 maven shaded 插件,修改包路徑(推薦使用該方法)

<dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>29.0-jre</version>
        </dependency>
</dependencies>

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <relocations>
                                <relocation>
                                    <pattern>com.google.common</pattern>
                                    <shadedPattern>your_guava.common</shadedPattern>
                                </relocation>
                            </relocations>
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/maven/**</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>      

maven-shade-plugin 插件可高效解決沖突雙方的包互相不相容情況,其原理是修改其中任意一方的依賴路徑來解決。

比如

package A 依賴package com.google.common.v1,

package C 依賴 package com.google.common.v2,

此時可以将