java with 如何使用Maven創建具有依賴關係的可執行JAR?




spring boot maven build jar (24)

我想將我的項目打包在一個可執行的JAR中進行分發。

如何將所有依賴JAR的Maven項目打包到我的輸出JAR中?


你可以結合使用maven-shade-pluginmaven-jar-plugin

  • maven-shade-plugin將您的類和所有依賴項打包在一個jar文件中。
  • 配置maven-jar-plugin以指定可執行jar的主類(請參閱設置類路徑 ,“使Jar可執行文件”一章)。

maven-jar-plugin示例POM配置:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>com.example.MyMainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

最後通過調用創建可執行jar:

mvn clean package shade:shade

您可以使用maven-shade插件來構建如下所示的超級jar

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

對我有用的東西是:

  <plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
      <execution>
        <id>unpack-dependencies</id>
        <phase>prepare-package</phase>
        <goals>
          <goal>unpack-dependencies</goal>
        </goals>
        <configuration>
          <outputDirectory>${project.build.directory}/classes</outputDirectory>
        </configuration>
      </execution>

    </executions>
  </plugin>


  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <executions>
      <execution>
        <id>unpack-dependencies</id>
        <phase>package</phase>
      </execution>
    </executions>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <classpathPrefix>lib/</classpathPrefix>
          <mainClass>SimpleKeyLogger</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>

我有特殊情況,因為我的依賴是系統一:

<dependency>
  ..
  <scope>system</scope>
  <systemPath>${project.basedir}/lib/myjar.jar</systemPath>
</dependency>

我更改了@ user189057提供的代碼更改:1)maven-dependency-plugin在“prepare-package”階段執行2)我正在將解壓縮的classess直接提取到“target / classes”


使用onejar插件將其構建為一個可執行jar文件,該文件將所有依賴jar包裝在其中。 這解決了我的問題,類似於此。 當使用程序集插件時,它將所有依賴jar解壓縮到源文件夾中並將它們重新打包為jar,它已經覆蓋了我在代碼中具有相同類名的所有類似實現。 onejar在這裡是一個簡單的解決方案。


您可以使用dependency-plugin在包階段之前在單獨的目錄中生成所有依賴項,然後將其包含在清單的類路徑中:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>theMainClass</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

或者使用${project.build.directory}/classes/lib作為OutputDirectory將所有jar文件集成到主jar中,但是您需要添加自定義類加載代碼來加載jar。


您可以將以下內容添加到pom.xml

<build>
<defaultGoal>install</defaultGoal>
<plugins>
  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
    </configuration>
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.3.1</version>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <mainClass>com.mycompany.package.MainClass</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>
  <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>com.mycompany.package.MainClass</mainClass>
        </manifest>
      </archive>
    </configuration>
    <executions>
      <execution>
        <id>make-my-jar-with-dependencies</id>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>
</build>

之後,您必須通過控制台切換到pom.xml所在的目錄。 然後你必須執行mvn程序集:單個然後你的可執行JAR文件將有希望構建。 使用cd ./target切換到輸出(目標)目錄並使用類似於 java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar的命令啟動jar時,可以檢查它。

我用Apache Maven 3.0.3測試了這個。


添加到pom.xml:

  <dependency>
            <groupId>com.jolira</groupId>
            <artifactId>onejar-maven-plugin</artifactId>
            <version>1.4.4</version>
  </dependency>

<plugin>
       <groupId>com.jolira</groupId>
       <artifactId>onejar-maven-plugin</artifactId>
       <version>1.4.4</version>
       <executions>
              <execution>
                     <goals>
                         <goal>one-jar</goal>
                     </goals>
              </execution>
       </executions>
</plugin>

而已。 接下來mvn包還將另外創建一個fat jar,包括所有依賴jar。


這也可以是一個選項,您將能夠構建您的jar文件

<build>
    <plugins>
        <plugin>
            <!-- Build an executable JAR -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>WordListDriver</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

我在博客上寫了一些不同的方法來做到這一點。

請參閱使用Apache Maven的可執行jar (WordPress)

或者executable-jar-with-maven-example (GitHub)

筆記

這些優點和缺點由Stephan提供。

用於手動部署

  • 優點
  • 缺點
    • 依賴性超出了最後的jar。

將依賴項複製到特定目錄

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <executions>
    <execution>
      <id>copy-dependencies</id>
      <phase>prepare-package</phase>
      <goals>
        <goal>copy-dependencies</goal>
      </goals>
      <configuration>
        <outputDirectory>${project.build.directory}/${project.build.finalName}.lib</outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

使Jar可執行文件和類路徑感知

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <addClasspath>true</addClasspath>
        <classpathPrefix>${project.build.finalName}.lib/</classpathPrefix>
        <mainClass>${fully.qualified.main.class}</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>

此時, jar實際上可以使用外部類路徑元素執行。

$ java -jar target/${project.build.finalName}.jar

製作可部署的檔案

jar文件只能與兄弟...lib/目錄一起執行。 我們需要使用目錄及其內容來部署存檔。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-antrun-plugin</artifactId>
  <executions>
    <execution>
      <id>antrun-archive</id>
      <phase>package</phase>
      <goals>
        <goal>run</goal>
      </goals>
      <configuration>
        <target>
          <property name="final.name" value="${project.build.directory}/${project.build.finalName}"/>
          <property name="archive.includes" value="${project.build.finalName}.${project.packaging} ${project.build.finalName}.lib/*"/>
          <property name="tar.destfile" value="${final.name}.tar"/>
          <zip basedir="${project.build.directory}" destfile="${final.name}.zip" includes="${archive.includes}" />
          <tar basedir="${project.build.directory}" destfile="${tar.destfile}" includes="${archive.includes}" />
          <gzip src="${tar.destfile}" destfile="${tar.destfile}.gz" />
          <bzip2 src="${tar.destfile}" destfile="${tar.destfile}.bz2" />
        </target>
      </configuration>
    </execution>
  </executions>
</plugin>

現在你有target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz) ,每個包含jarlib/*

Apache Maven Assembly插件

  • 優點
  • 缺點
    • 沒有類重定位支持(如果需要類重定位,請使用maven-shade-plugin)。
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <archive>
          <manifest>
            <mainClass>${fully.qualified.main.class}</mainClass>
          </manifest>
        </archive>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </execution>
  </executions>
</plugin>

你有target/${project.bulid.finalName}-jar-with-dependencies.jar

Apache Maven Shade插件

  • 優點
  • 缺點
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <shadedArtifactAttached>true</shadedArtifactAttached>
        <transformers>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>${fully.qualified.main.class}</mainClass>
          </transformer>
        </transformers>
      </configuration>
    </execution>
  </executions>
</plugin>

你有target/${project.build.finalName}-shaded.jar

onejar - Maven的插件

  • 優點
  • 缺點
    • 自2012年以來未得到積極支持
<plugin>
  <!--groupId>org.dstovall</groupId--> <!-- not available on the central -->
  <groupId>com.jolira</groupId>
  <artifactId>onejar-maven-plugin</artifactId>
  <executions>
    <execution>
      <configuration>
        <mainClass>${fully.qualified.main.class}</mainClass>
        <attachToBuild>true</attachToBuild>
        <!-- https://code.google.com/p/onejar-maven-plugin/issues/detail?id=8 -->
        <!--classifier>onejar</classifier-->
        <filename>${project.build.finalName}-onejar.${project.packaging}</filename>
      </configuration>
      <goals>
        <goal>one-jar</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Spring Boot Maven插件

  • 優點
  • 缺點
    • 添加潛在的不必要的Spring和Spring Boot相關類。
<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>repackage</goal>
      </goals>
      <configuration>
        <classifier>spring-boot</classifier>
        <mainClass>${fully.qualified.main.class}</mainClass>
      </configuration>
    </execution>
  </executions>
</plugin>

你有target/${project.bulid.finalName}-spring-boot.jar


您可以使用maven-dependency-plugin,但問題是如何創建可執行JAR。 要做到這一點,需要對Matthew Franglen的響應進行以下更改(順便說一句,使用依賴插件從清理目標開始時需要更長時間才能構建):

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>fully.qualified.MainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>unpack-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>unpack-dependencies</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
    <resources>
        <resource>
            <directory>${basedir}/target/dependency</directory>
        </resource>
    </resources>
</build>

長期使用maven程序集插件 ,但我找不到"already added, skipping"問題的解決方案。 現在,我正在使用另一個插件 - onejar-maven-plugin 。 下面的例子( mvn package構建jar):

<plugin>
    <groupId>org.dstovall</groupId>
    <artifactId>onejar-maven-plugin</artifactId>
    <version>1.3.0</version>
    <executions>
        <execution>
            <configuration>
                <mainClass>com.company.MainClass</mainClass>
            </configuration>
            <goals>
                <goal>one-jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

您需要為該插件添加存儲庫:

<pluginRepositories>
    <pluginRepository>
        <id>onejar-maven-plugin.googlecode.com</id>
        <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
    </pluginRepository>
</pluginRepositories>

對於任何尋找從超級jar中排除特定依賴項的選項的人來說,這是一個對我有用的解決方案:

<project...>
<dependencies>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.11</artifactId>
            <version>1.6.1</version>
            <scope>provided</scope> <=============
        </dependency>
</dependencies>
<build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>...</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

所以它不是mvn-assembly-plugin的配置,而是依賴的屬性。


這是我發現的最佳方式:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
      <archive>
        <manifest>
        <addClasspath>true</addClasspath>
        <mainClass>com.myDomain.etc.MainClassName</mainClass>
        <classpathPrefix>dependency-jars/</classpathPrefix>
        </manifest>
      </archive>
    </configuration>
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.5.1</version>
    <executions>
      <execution>
        <id>copy-dependencies</id>
        <phase>package</phase>
        <goals>
            <goal>copy-dependencies</goal>
        </goals>
        <configuration>
            <outputDirectory>
               ${project.build.directory}/dependency-jars/
            </outputDirectory>
        </configuration>
      </execution>
    </executions>
  </plugin>

使用此配置,所有依賴項都將位於/dependency-jars。我的應用程序沒有Main類,只有上下文,但我的一個依賴項確實有一個Mainclass(com.myDomain.etc.MainClassName)啟動JMX服務器,並接收一個start或一個stop參數。所以有了這個我能夠像這樣啟動我的應用程序:

java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start

我等待它對你們大家都有用。


採取未答复的答案並重新格式化,我們有:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>fully.qualified.MainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>
    </plugins>
</build>

接下來,我建議將其作為構建的一部分,而不是明確調用。 要使其成為構建中不可或缺的一部分,請將此插件添加到pom.xml並將其綁定到package生命週期事件。 但是,一個問題是你需要調用assembly:single如果將它放在pom.xml中, assembly:single目標,而如果從命令行手動執行它,則調用'assembly:assembly'。

<project>
  [...]
  <build>
      <plugins>
          <plugin>
              <artifactId>maven-assembly-plugin</artifactId>
              <configuration>
                  <archive>
                      <manifest>
                          <addClasspath>true</addClasspath>
                          <mainClass>fully.qualified.MainClass</mainClass>
                      </manifest>
                  </archive>
                  <descriptorRefs>
                      <descriptorRef>jar-with-dependencies</descriptorRef>
                  </descriptorRefs>
              </configuration>
              <executions>
                  <execution>
                      <id>make-my-jar-with-dependencies</id>
                      <phase>package</phase>
                      <goals>
                          <goal>single</goal>
                      </goals>
                  </execution>
              </executions>
          </plugin>
      [...]
      </plugins>
    [...]
  </build>
</project>

我不會像其他人之前已經做過的那樣直接回答這個問題,但我真的很想知道將所有依賴項嵌入項目的jar本身是否是個好主意。

我看到了重點(易於部署/使用),但它取決於你的項目的用例(並且可能有替代方案(見下文))。

如果你完全獨立使用它,為什麼不。

但是如果你在其他環境中使用你的項目(比如在webapp中,或者放在其他jar所在的文件夾中),你的類路徑中可能有jar副本(文件夾中的那​​些,jar中的那個)。 也許不是出價協議,但我通常會避免這種情況。

一個很好的選擇:

  • 將您的應用程序部署為.zip / .war:存檔包含項目的jar和所有相關的jar;
  • 使用動態類加載器機制(請參閱Spring,或者您可以輕鬆地自己完成),以獲得項目的單個入口點(單個類開始 - 請參閱另一個答案的Manifest機制),它將(動態)添加到當前的classpath所有其他需要的罐子。

像這樣,最後只有一個清單和一個“特殊的動態類加載器主”,你可以用以下方式啟動你的項目:

java -jar ProjectMainJar.jar com..projectName.MainDynamicClassLoaderClass

如果你想從命令行本身。 只需從項目路徑運行以下命令即可

mvn彙編:彙編


<build>
  <plugins>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <configuration>
        <archive>
          <manifest>
            <mainClass>fully.qualified.MainClass</mainClass>
          </manifest>
        </archive>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </plugin>
  </plugins>
</build>

你運行它

mvn clean compile assembly:single

應該在彙編之前添加編譯目標:單個或者不包括您自己項目中的代碼。

在評論中查看更多詳情。

通常,此目標與要自動執行的構建階段相關聯。 這可確保在執行mvn install或執行部署/發佈時構建JAR。

<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>fully.qualified.MainClass</mainClass>
      </manifest>
    </archive>
    <descriptorRefs>
      <descriptorRef>jar-with-dependencies</descriptorRef>
    </descriptorRefs>
  </configuration>
  <executions>
    <execution>
      <id>make-assembly</id> <!-- this is used for inheritance merges -->
      <phase>package</phase> <!-- bind to the packaging phase -->
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Ken Liu在我看來是正確的。 maven依賴插件允許您擴展所有依賴項,然後您可以將其視為資源。 這允許您將它們包含在工件中。 使用程序集插件會創建一個難以修改的輔助工件 - 在我的情況下,我想添加自定義清單條目。 我的pom最終成了:

<project>
 ...
 <build>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
     <execution>
      <id>unpack-dependencies</id>
      <phase>package</phase>
      <goals>
       <goal>unpack-dependencies</goal>
      </goals>
     </execution>
    </executions>
   </plugin>
  </plugins>
  ...
  <resources>
   <resource>
    <directory>${basedir}/target/dependency</directory>
    <targetPath>/</targetPath>
   </resource>
  </resources>
 </build>
 ...
</project>


已有數百萬的答案,<mainClass>如果您不需要將entryPoint添加到您的應用程序中,我想添加您不需要的內容。例如,API可能不一定有main方法。

maven插件配置

  <build>
    <finalName>log-enrichment</finalName>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>

建立

mvn clean compile assembly:single

校驗

ll target/
total 35100
drwxrwx--- 1 root vboxsf     4096 Sep 29 16:25 ./
drwxrwx--- 1 root vboxsf     4096 Sep 29 16:25 ../
drwxrwx--- 1 root vboxsf        0 Sep 29 16:08 archive-tmp/
drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 classes/
drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 generated-sources/
drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 generated-test-sources/
-rwxrwx--- 1 root vboxsf 35929841 Sep 29 16:10 log-enrichment-jar-with-dependencies.jar*
drwxrwx--- 1 root vboxsf        0 Sep 29 16:08 maven-status/

maven-assembly-plugin對我很有用。我花了幾個小時使用maven-dependency-plugin並且無法使其工作。主要原因是我必須在配置部分明確定義應該包含的工件項,如documentation中所述。有一個例子,當你想要使用它時,例如:mvn dependency:copy,其中沒有包含任何artifactItem但它不起作用。


我在這裡嘗試了最多投票的答案,並且能夠讓jar可以運行。 但程序運行不正常。 我不知道原因是什麼。 當我嘗試從Eclipse運行時,我得到了不同的結果,但是當我從命令行運行jar時,我得到了不同的結果(它因程序特定的運行時錯誤而崩潰)。

我有一個與OP類似的要求,因為我的項目有太多(Maven)依賴項。 幸運的是,唯一對我有用的解決方案是使用Eclipse 。 非常簡單,非常直接。 這不是OP的解決方案,但對於具有類似要求但具有許多Maven依賴性的人來說,它是一種解決方案,

1)只需右鍵單擊項目文件夾(在Eclipse中),然後選擇“ Export

2)然後選擇Java - > Runnable Jar

3)將要求您選擇jar文件的位置

4)最後,選擇具有要運行的Main方法的類,並Package dependencies with the Jar file選擇Package dependencies with the Jar file然後單擊Finish


我比較了這篇文章中提到的樹插件。我生成了2個罐子和一個包含所有罐子的目錄。我比較了結果,絕對是maven-shade-plugin是最好的。我的挑戰是我有多個需要合併的spring資源,以及jax-rs和JDBC服務。與maven-assembly-plugin相比,它們都被shade插件正確合併。在這種情況下,彈簧將失敗,除非您將它們複製到您自己的資源文件夾並手動合併它們一次。兩個插件都輸出正確的依賴樹。我有多個範圍,如測試,提供,編譯等測試和提供被兩個插件跳過。它們都產生了相同的清單,但我能夠使用變壓器將許可證與陰影插件合併。有了maven-dependency-plugin,你當然不會這些問題是因為沒有提取罐子。但正如其他一些人指出的那樣,你需要攜帶一個額外的文件才能正常工作。這是pom.xml的一個片段

            <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/lib</outputDirectory>
                        <includeScope>compile</includeScope>
                        <excludeTransitive>true</excludeTransitive>
                        <overWriteReleases>false</overWriteReleases>
                        <overWriteSnapshots>false</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>com.rbccm.itf.cdd.poller.landingzone.LandingZonePoller</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                <execution>
                    <id>make-my-jar-with-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.4.3</version>
            <configuration>
                <shadedArtifactAttached>false</shadedArtifactAttached>
                <keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/services/javax.ws.rs.ext.Providers</resource>
                    </transformer>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.factories</resource>
                    </transformer>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.handlers</resource>
                    </transformer>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.schemas</resource>
                    </transformer>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.tooling</resource>
                    </transformer>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer">
                    </transformer>
                </transformers>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

使用maven-shade-plugin將所有依賴項打包到一個超級jar中。 它還可以通過指定主類來構建可執行jar。 在嘗試使用maven-assembly和maven-jar之後,我發現這個插件最適合我的需求。

我發現這個插件特別有用,因為它合併了特定文件的內容而不是覆蓋它們。 如果資源文件在jar中具有相同的名稱,並且插件嘗試打包所有資源文件,則需要這樣做

見下面的例子

      <plugins>
    <!-- This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies. -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>1.4</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <artifactSet>
                        <!-- signed jars-->
                            <excludes>
                                <exclude>bouncycastle:bcprov-jdk15</exclude>
                            </excludes>
                        </artifactSet>

                         <transformers>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <!-- Main class -->
                                <mainClass>com.main.MyMainClass</mainClass>
                            </transformer>
                            <!-- Use resource transformers to prevent file overwrites -->
                            <transformer 
                                 implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>properties.properties</resource>
                            </transformer>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                                <resource>applicationContext.xml</resource>
                            </transformer>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>META-INF/cxf/cxf.extension</resource>
                            </transformer>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                                <resource>META-INF/cxf/bus-extensions.xml</resource>
                            </transformer>
                     </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>

    </plugins>






executable-jar