我們在很多場景下會碰到j(luò)ava包沖突的問題:
- 代碼由第三方開發(fā)伍茄,無法對包名或依賴做管控
- 跑在同一個進(jìn)程里的代碼敷矫,更新步調(diào)不一致。比如底層sdk整葡,jvm agent。這些組件更新頻率較低
最出名的解決路數(shù)還是類加載機(jī)制俱萍,諸如flink,osgi都給我們提供了很多方案岳颇,這些方案都非常重型话侧。在代碼可信任的情況下悲立,其中有一個很輕量級的解決方案就是maven-shade包。
舉個例子寥殖,比方說我想在java agent中打印日志,但是又不希望和業(yè)務(wù)代碼中的log4j等沖突粤策,agent里依賴的pom文件是這樣子的:
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>2.13.3</version>
</dependency>
</dependencies>
這里我們log4j,slf4j可能用的版本太高或者太低柔吼,我們就可以通過打shade包的方式修改log4j和slf4j的包名,避免和業(yè)務(wù)沖突
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>org.slf4j:slf4j-api</include>
<include>org.apache.logging.log4j:log4j-api</include>
<include>org.apache.logging.log4j:log4j-core</include>
<include>org.apache.logging.log4j:log4j-slf4j-impl</include>
<include>org.apache.logging.log4j:log4j-jcl</include>
</includes>
</artifactSet>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<relocations>
<relocation>
<pattern>org.slf4j</pattern>
<shadedPattern>com.github.shoothzj.org.slf4j</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.logging</pattern>
<shadedPattern>com.github.shoothzj.org.apache.logging</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
通過上面的配置胡本,artifactSet選擇要修改的pom依賴侧甫,通過relocation修改包名咒锻,達(dá)到不沖突的效果。mvn clean package 后查看效果
image-20201230145531225
可以發(fā)現(xiàn)敦捧,包名已經(jīng)被修改完成,達(dá)到了避免沖突的目的。