簡體   English   中英

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

[英]How can I create an executable JAR with dependencies using Maven?

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

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

<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

編譯目標應該在 assembly:single 之前添加,否則不包括您自己項目中的代碼。

在評論中查看更多詳細信息。


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

<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>
      <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>
  </plugins>
</build>

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

<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。

請參閱可執行的 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 程序集插件

  • 優點
  • 缺點
    • 沒有類重定位支持(如果需要類重定位,請使用 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 陰影插件

  • 優點
  • 缺點
<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

接受未回答的答案並重新格式化,我們有:

<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生命周期事件。 但是,一個問題是,如果將其放在 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>

使用 maven-shade-plugin 將所有依賴項打包到一個 uber-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>

您可以使用 maven-shade 插件來構建一個 uber 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>

長期使用maven組裝插件,但我找不到"already added, skipping"問題的解決方案。 現在,我正在使用另一個插件 - onejar-maven-plugin 下面的示例( mvn package build 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>

您可以使用 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>

您可以將以下內容添加到您的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 assembly:single然后你的可執行 JAR 文件與依賴項將有望被構建。 您可以在使用cd ./target切換到輸出(目標)目錄並使用類似於java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar的命令啟動 jar 時檢查它。

我用Apache Maven 3.0.3對此進行了測試。

我瀏覽了這些響應中的每一個,希望制作一個包含所有依賴項的胖可執行 jar,但它們都不能正常工作。 答案是陰影插件,它非常簡單明了。

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-shade-plugin</artifactId>
      <version>2.3</version>
      <executions>
         <!-- Run shade goal on package phase -->
        <execution>
        <phase>package</phase>
        <goals>
            <goal>shade</goal>
        </goals>
        <configuration>
          <transformers>
             <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                <mainClass>path.to.MainClass</mainClass>
             </transformer>
          </transformers>
        </configuration>
          </execution>
      </executions>
    </plugin>

請注意,您的依賴項需要具有編譯或運行時范圍才能正常工作。

這個例子來自 mkyong.com

如果您真的想在單個結果 JAR 中重新打包其他 JAR 內容,另一個選擇是Maven Assembly 插件 它解壓縮然后通過<unpack>true</unpack>將所有內容重新打包到一個目錄中。 然后你會有第二遍將它構建到一個巨大的 JAR 中。

另一種選擇是 OneJar 插件 這一步完成了上述重新打包操作。

您可以結合使用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

它將像這樣工作:

<plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>unpack-dependencies</id>
            <phase>generate-resources</phase>
            <goals>
                <goal>unpack-dependencies</goal>
            </goals>
        </execution>
    </executions>
</plugin>

解包必須在 generate-resources 階段,否則它不會被包含在資源中。

在我看來,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>

這是Credit Karma使用的Maven可執行jar插件。 它使用能夠從嵌套jar加載類的類加載器創建一個jar罐。 這使您可以在dev和prod中具有相同的類路徑,並且仍將所有類保留在單個簽名的jar文件中。

https://github.com/creditkarma/maven-exec-jar-plugin

這是一篇博客文章,其中詳細介紹了該插件及其制作原因: https//engineering.creditkarma.com/general-engineering/new-executable-jar-plugin-available-apache-maven/

使用 maven-assembly-plugin-2.2.1 定位共享程序集文件有問題嗎?

嘗試使用descriptorId 配置參數而不是descriptors/descriptor 或descriptorRefs/descriptorRef 參數。

他們都沒有做你需要的事情:在類路徑中查找文件。 當然,您需要在 maven-assembly-plugin 的類路徑中添加共享程序集所在的包(見下文)。 如果您使用的是 Maven 2.x(不是 Maven 3.x),您可能需要在 pluginManagement 部分的最頂層父 pom.xml 中添加此依賴項。

有關更多詳細信息,請參閱內容。

類:org.apache.maven.plugin.assembly.io.DefaultAssemblyReader

例子:

        <!-- Use the assembly plugin to create a zip file of all our dependencies. -->
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.2.1</version>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <descriptorId>assembly-zip-for-wid</descriptorId>
                    </configuration>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>cz.ness.ct.ip.assemblies</groupId>
                    <artifactId>TEST_SharedAssemblyDescriptor</artifactId>
                    <version>1.0.0-SNAPSHOT</version>
                </dependency>
            </dependencies>
        </plugin>

為了解決這個問題,我們將使用 Maven 程序集插件,它將 JAR 及其依賴 JAR 一起創建到單個可執行 JAR 文件中。 只需在您的 pom.xml 文件中添加以下插件配置。

<build>
   <pluginManagement>
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
               <archive>
                  <manifest>
                     <addClasspath>true</addClasspath>
                     <mainClass>com.your.package.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>
   </pluginManagement>
</build>

完成此操作后,不要忘記使用此命令運行 MAVEN 工具 mvn clean compile assembly:single

http://jkoder.com/maven-creating-a-jar-together-with-its-dependency-jars-into-a-single-executable-jar-file/

使用onejar插件將其構建為一個可執行jar文件,該文件將所有依賴jar打包在其中。 那解決了我與此類似的問題。 當使用assembly plugin時,它將所有依賴項jar都解壓縮到源文件夾中,然后將其重新打包為jar,它已經覆蓋了我在代碼內部具有相同類名的所有類似實現。 在這里,onejar是一個簡單的解決方案。

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

我明白了這一點(易於部署/使用),但這取決於您的項目的用例(並且可能有替代方案(見下文))。

如果您完全獨立使用它,為什么不呢。

但是,如果您在其他上下文中使用您的項目(例如在 web 應用程序中,或者放在其他 jar 所在的文件夾中),您的類路徑中可能有 jar 重復項(文件夾中的那些,jar 中的那個)。 也許不是投標交易,但我通常會避免這種情況。

一個很好的選擇:

  • 將您的應用程序部署為 .zip / .war :存檔包含您項目的 jar 和所有依賴的 jar;
  • 使用動態類加載器機制(請參閱 Spring,或者您可以自己輕松地做到這一點)擁有項目的單個入口點(啟動單個類 - 請參閱另一個答案的清單機制),這將(動態)添加到當前類路徑所有其他需要的罐子。

像這樣,最后只有一個清單和一個“特殊的動態類加載器主程序”,您可以使用以下命令開始您的項目:

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

對我有用的是:

  <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)我將解壓縮的類直接提取到“目標/類”

這是我發現的最好方法:

  <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類,只有上下文類,但我的一個依賴項確實有一個Main類 ( com.myDomain.etc.MainClassName ),它啟動 JMX 服務器並接收startstop參數。 所以有了這個我能夠像這樣啟動我的應用程序:

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

我等待它對大家有用。

我比較了這篇文章中提到的樹插件。 我生成了 2 個 jar 和一個包含所有 jar 的目錄。 我比較了結果,肯定 maven-shade-plugin 是最好的。 我的挑戰是我有多個需要合並的 spring 資源,以及 jax-rs 和 JDBC 服務。 與 maven-assembly-plugin 相比,它們都被 shade 插件正確合並。 在這種情況下,除非您將它們復制到自己的資源文件夾並手動合並一次,否則 spring 將失敗。 兩個插件都輸出正確的依賴樹。 我有多個范圍,如測試、提供、編譯等,兩個插件都跳過了測試和提供的范圍。 他們都產生了相同的清單,但我能夠使用他們的轉換器將許可證與陰影插件合並。 使用 maven-dependency-plugin 當然你沒有這些問題,因為 jars 沒有被提取。 但就像其他人指出的那樣,您需要攜帶一個額外的文件才能正常工作。 這是 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>

對於任何尋找從 uber-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 的配置,而是依賴項的屬性。

要從命令行本身創建可執行 JAR,只需從項目路徑運行以下命令:

mvn assembly:assembly

已經有數百萬個答案,如果您不需要將 entryPoint 添加到您的應用程序,我想添加您不需要<mainClass> 例如,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/

我在這里嘗試了投票最多的答案,並且能夠讓 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然后單擊Finish

這也可以是一個選項,您將能夠構建您的 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>

您也可以使用此插件,它非常好,我用它來包裝我的罐子http://sonatype.github.io/jarjar-maven-plugin/

添加到 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。

我希望我的經驗可以幫助別人。 我想將我的應用程序 Spring(使用 CAS 客戶端)遷移到 Spring Boot 1.5。 我遇到了很多問題,例如:

沒有主要清單屬性,在 target/cas-client-web.jar

我試圖制作一個具有所有依賴項的獨特 jar。 在互聯網上搜索后,我可以用以下幾行來做到這一點:

         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <fork>true</fork>
                <mainClass>${start-class}</mainClass>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>${start-class}</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>

start-class是我的主要課程:

<properties>
    <java.version>1.8</java.version>
    <start-class>com.test.Application</start-class>
</properties>

我的申請是:

package com.test;

import java.util.Arrays;

import com.test.TestProperties;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;


@SpringBootApplication
@EnableAutoConfiguration
@EnableConfigurationProperties({TestProperties.class})
public class Application {

public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}

@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> {

        System.out.println("Let's inspect the beans provided by Spring Boot:");

        String[] beanNames = ctx.getBeanDefinitionNames();
        Arrays.sort(beanNames);
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }

    };
}

}

嘗試了多種解決方案,但在我們想要創建一個不可執行的胖 jar 的場景中完美運行的解決方案,其中外部系統的所有內部依賴項都與以前沒有相關性。 產品場景測試。

將其包含在 pom.xml 中

<?xml version="1.0" encoding="UTF-8"?>
<build>
   <sourceDirectory>src</sourceDirectory>
   <plugins>
      <plugin>
         <artifactId>maven-compiler-plugin</artifactId>
         <version>3.8.1</version>
         <configuration>
            <source>1.8</source>
            <target>1.8</target>
         </configuration>
      </plugin>
      <plugin>
         <artifactId>maven-assembly-plugin</artifactId>
         <configuration>
            <descriptorRefs>
               <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
         </configuration>
      </plugin>
   </plugins>
</build>


運行命令以構建胖 jar->> mvn assembly:assembly

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

這篇博文展示了另一種結合 maven-jar 和 maven-assembly 插件的方法。 使用博客文章中的程序集配置 xml,還可以控制是否擴展依賴項或僅將依賴項收集在文件夾中並由清單中的類路徑條目引用:

理想的解決方案是將 jar 包含在 lib 文件夾中,並且主 jar 的 manifest.mf 文件包含類路徑中的所有 jar。

正是在這里描述了一個: https ://caffebig.wordpress.com/2013/04/05/executable-jar-file-with-dependent-jars-using-maven/

mvn clean install -U dependency:copy-dependencies

.jar 將在名為“ target ”的文件夾中生成,與“ src ”文件夾位於同一根目錄中。

好的,這就是我的解決方案。 我知道它沒有使用 pom.xml 文件。 但是我的程序在 Netbeans 上編譯和運行時遇到了問題,但是當我嘗試 Java -jar MyJarFile.jar 時它失敗了。 現在,我並不完全了解 Maven,我認為這就是為什么讓 Netbeans 8.0.2 無法將我的 jar 文件包含在庫中以將它們放入 jar 文件中的原因。 我正在考慮如何在 Eclipse 中使用沒有 Maven 的 jar 文件。

可以編譯所有依賴項和插件的是 Maven。 不是 Netbeans。 (如果您可以獲得 Netbeans 並能夠使用 java .jar 來執行此操作,請告訴我如何 (^.^)v )

[已解決 - 適用於 Linux] 通過打開終端。

然后

cd /MyRootDirectoryForMyProject

下一個

mvn org.apache.maven.plugins:maven-compiler-plugin:compile

下一個

mvn install

這將在目標目錄中創建 jar 文件。

MyJarFile-1.0-jar-with-dependencies.jar

現在

cd target

(您可能需要運行: chmod +x MyJarFile-1.0-jar-with-dependencies.jar

最后

java -jar MyJarFile-1.0-jar-with-dependencies.jar

請參見

https://cwiki.apache.org/confluence/display/MAVEN/LifecyclePhaseNotFoundException

我將把這個解決方案發布在有類似問題的其他幾個頁面上。 希望我能從一周的挫折中拯救某人。

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.4.1</version>
            <configuration>
                <!-- get all project dependencies -->
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <!-- bind to the packaging phase -->
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM