提问



我想将我的项目打包在一个可执行的JAR中进行分发。


如何将所有依赖JAR的Maven项目打包到我的输出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


编译目标应该在汇编之前添加:单个或者不包含您自己项目中的代码。


在评论中查看更多详情。





通常,此目标与要自动执行的构建阶段相关联。这可确保在执行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>

其它参考1


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

其它参考2


我在博客上写了一些不同的方法来做到这一点。


请参阅使用Apache Maven的可执行jar(WordPress)[78]


或者可执行jar-with-maven-example(GitHub)[79]


备注



这些利弊由斯蒂芬提供。





用于手动部署




  • 赞成

  • 缺点


    • 依赖性不在最后一个罐子里。




将依赖项复制到特定目录



<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 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-行家-插件




  • 赞成

  • 缺点


    • 自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

其它参考3


采取未答复的答案并重新格式化,我们有:


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

其它参考4


使用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>

其它参考5


长期使用 maven程序集插件,但我找不到"already added, skipping"问题的解决方案。现在,我正在使用另一个插件 - onejar-maven-plugin 。下面的示例(mvn package build jar): [82]


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

其它参考6


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

其它参考7


如果你真的想要在你的单个结果JAR中重新打包其他JAR内容,那么另一个选择是Maven Assembly插件。它解压缩然后通过<unpack>true</unpack>将所有内容重新打包到一个目录中。然后你会有第二遍将它建成一个巨大的JAR。[83]


另一种选择是OneJar插件。这样就可以一步完成上述重新包装操作。[84]

其它参考8


您可以将以下内容添加到 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-的命令启动jar dependencies.jar 即可。


我用 Apache Maven 3.0.3 测试了这个。

其它参考9


你可以结合maven-shade-pluginmaven-jar-plugin



  • maven-shade-plugin将您的类和所有依赖项打包在一个jar文件中。

  • 配置maven-jar-plugin以指定可执行jar的主类(请参阅设置类路径,使Jar可执行一章)。



maven-jar-plugin的示例POM配置:[85]


        <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

其它参考10


我经历了这些响应中的每一个都希望制作一个包含所有依赖项的胖可执行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 [86]

其它参考11


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>

其它参考12


这是我们在Credit Karma使用的Maven的可执行jar插件。它创建了一个罐子罐,里面有一个能够从嵌套jar中加载类的类加载器。这允许你在dev和prod中拥有相同的类路径,并且仍然保留所有类在一个签名的jar文件中。


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


这是一篇博客文章,其中详细介绍了该插件以及我们制作插件的原因:
https://engineering.creditkarma.com/general-engineering/new-executable-jar-plugin-available-apache-maven/[88]

其它参考13


使用onejar插件将其构建为一个可执行jar文件,该文件将所有依赖jar包装在其中。这解决了我的问题,类似于此。当使用程序集插件时,它将所有依赖jar解压缩到源文件夹中并将它们重新打包为jar,它已经覆盖了我在代码中具有相同类名的所有类似实现。 onejar在这里是一个简单的解决方案。[89]

其它参考14


使用maven-assembly-plugin-2.2.1查找共享程序集文件的问题?


尝试使用descriptorId配置参数而不是descriptors/descriptor或descriptorRefs/descriptorRef参数。


他们都没有做你需要的:在类路径上查找文件。
当然,您需要在maven-assembly-plugin的类路径中添加共享程序集所在的包(请参阅下文)。
如果您正在使用Maven 2.x(而不是Maven 3.x),则可能需要在pluginManagement部分的最顶级父pom.xml中添加此依赖项。


有关详细信息,请参阅此内容。[90]


类: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>

其它参考15


它应该是这样的:


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


解包必须处于生成资源阶段,因为如果处于打包阶段,则不会将其作为资源包含在内。
尝试清除包装,你会看到。

其它参考16


我不会直接回答这个问题,因为其他人之前已经这样做了,但我真的很想知道将所有依赖项嵌入项目的jar本身是不是一个好主意。


我看到了重点(易于部署/使用),但它取决于你的项目的用例(并且可能有替代方案(见下文))。


如果你完全独立使用它,为什么不。


但是如果你在其他环境中使用你的项目(比如在webapp中,或者放在其他jar所在的文件夹中),你的类路径中可能有jar副本(文件夹中的那些,jar中的那个)。也许不是出价协议,但我通常会避免这种情况。


一个很好的选择:



  • 将您的应用程序部署为.zip/.war:存档包含项目的jar和所有相关的jar;

  • 使用动态类加载器机制(请参阅Spring,或者您可以轻松地自己完成此操作)以获得项目的单个入口点(单个类开始 - 请参阅另一个答案的Manifest机制),这将添加(动态) )到当前的类路径所有其他需要的罐子。



像这样,最后只有一个清单和一个特殊的动态类加载器主,你可以用以下方式启动你的项目:


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

其它参考17


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

其它参考18


如果你想从命令行本身。只需从项目路径运行以下命令即可


mvn汇编:汇编

其它参考19


你也可以使用这个插件,这是非常好的,我用它来包装我的罐子http://sonatype.github.io/jarjar-maven-plugin/[91]

其它参考20


对我有用的东西是:


  <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直接提取到目标/类

其它参考21


我在这里尝试了最多投票的答案,并且能够让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

其它参考22


这是我发现的最佳方式:


  <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


我等待它对你们大家都有用。

其它参考23


为了解决这个问题,我们将使用Maven Assembly Plugin,它将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/[92]

其它参考24


maven-assembly-plugin对我很有用。
我花了几个小时使用maven-dependency-plugin并且无法使其工作。主要原因是我必须在配置部分明确定义应该包含的工件项,如文档中所述。
当你想要使用它时,有一个例子:mvn dependency:copy,其中没有包含任何artifactItem但它不起作用。[93]

其它参考25


这也可以是一个选项,您将能够构建您的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>

其它参考26


我比较了这篇文章中提到的树插件。我生成了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>

其它参考27


已经有数百万的答案,如果你不需要在你的应用程序中添加entryPoint,我想补充一下你不需要<mainClass>例如,API可能不一定有main方法。


maven plugin config



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

其它参考28


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

其它参考29


这篇博文显示了另一种结合maven-jar和maven-assembly插件的方法。使用博客文章中的程序集配置xml,如果依赖项将被扩展,或者只是在文件夹中收集并由清单中的类路径条目引用,也可以控制它:



  理想的解决方案是将jar包含在lib文件夹中,主jar的manifest.mf文件包含classpath中的所有jar。



确切地说,这里描述的是:https://caffebig.wordpress.com/2013/04/05/executable-jar-file-with-dependent-jars-using-maven/[94]