在解決java jar包衝突的時候須要用到shade插件,好比flink 已經自帶了protobuf的包,可是咱們想使用另外一個版本的protobuf 包,這時候咱們就可使用shade插件打包,不然會報版本相關的錯誤。java
Apache maven shade plugin提供把工程的artifact及其依賴打包到一個uber-jar中並能隱藏起來(好比重命名),shade插件僅僅有一個功能就是建立一個shaded包。
那什麼是uber-jar呢,uber在德語中是above或over的意思,在這裏表示是從單一的jar提高到「over-jar」,即把全部的依賴都定義到一個jar文件裏。
好了,如今咱們知道shade插件的基本做用了,如今從官網給出的幾個例子看看實際的應用。apache
這是官網直譯的標題,用咱們容易理解的就是經過shade插件咱們能夠爲生成的那個jar包選擇包含哪些依賴以及排除哪些依賴。
1. 支持兩種操做include和exclude
2. 配置格式:groupId:artifactId[[:type]:classifier],至少包含groupid和artifactid,type和類名可選
3. 支持’*’ 和 ‘?’執行通配符匹配
好比,一個示例以下:
api
project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.0.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <artifactSet> <excludes> <exclude>classworlds:classworlds</exclude> <exclude>junit:junit</exclude> <exclude>jmock:*</exclude> <exclude>*:xml-apis</exclude> <exclude>org.apache.maven:lib:tests</exclude> <exclude>log4j:log4j:jar:</exclude> </excludes> </artifactSet> </configuration> </execution> </executions> </plugin> </plugins> </build> ... </project>
官網是「Relocating Classes」,若是一個uber-jar會被其餘項目引用,uber-jar中依賴的類可能會致使類定位衝突(因爲不一樣版本的jar包引發),咱們能夠經過shade插件來將被隱藏的類重定位以使該類只在該uber-jar中使用,這種方式也常常被用來解決jar包衝突問題。
示例以下:
maven
<project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.0.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <relocations> <relocation> <pattern>org.codehaus.plexus.util</pattern> <shadedPattern>org.shaded.plexus.util</shadedPattern> <excludes> <exclude>org.codehaus.plexus.util.xml.Xpp3Dom</exclude> <exclude>org.codehaus.plexus.util.xml.pull.*</exclude> </excludes> </relocation> </relocations> </configuration> </execution> </executions> </plugin> </plugins> </build> ... </project>
這指示插件經過移動相應的JAR文件條目並重寫受影響的字節碼( JAR file entries and rewritting the affected bytecode),將org.codehaus.plexus.util包以及子包中的類從組件org.shaded.plexus.util
中移到org.shaded.plexus.util
包中。Xpp3Dom類和pull其餘類將保留在原始包中。ui
默認狀況下,當執行installed/deployed時候,會默認生成兩個jar包,一個以-shaded結尾,這個咱們能夠配置更改,示例以下:spa
<project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.0.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <shadedClassifierName>myName</shadedClassifierName> <!-- Any name that makes sense --> </configuration> </execution> </executions> </plugin> </plugins> </build> ... </project>
則會生成以-myName結尾的jar包。插件
要建立一個可執行uber-jar包,也能夠將入口添加進來,示例以下:code
<project> <groupId>shade.test</groupId> <artifactId>shade.test</artifactId> <version>1.0-SNAPSHOT</version> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.0.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>Main</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> ... </project>