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

如何使Maven项目将所有依赖JAR打包到输出JAR中?


当前回答

参见maven示例的可执行jar(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文件可执行并支持Classpath

<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),每个文件都包含jar和lib/*。


Apache Maven程序集插件

赞成的意见欺骗不支持类重新定位(如果需要类重新定位,请使用maven shade插件)。

<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.build.finalName}-jar-with-dependences.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.build.finalName}-spring-boot.jar。

其他回答

如果您真的想重新打包单个结果JAR中的其他JAR内容,另一个选项是Maven Assembly插件。它通过<unpack>true</unpack>解包,然后将所有内容重新打包到一个目录中。然后,您将有第二个过程,将其构建到一个大型JAR中。

另一个选项是OneJar插件。这将在一个步骤中执行上述重新打包操作。

我在这里尝试了投票最多的答案,并且能够运行JAR文件。但程序没有正确运行。我不知道是什么原因。当我尝试从Eclipse运行时,会得到不同的结果,但当我从命令行运行JAR文件时,会获得不同的结果(它会因程序特定的运行时错误而崩溃)。

我有一个与OP类似的需求,只是我的项目有太多(Maven)依赖项。幸运的是,唯一对我有效的解决方案是使用Eclipse。它非常简单和直接。这不是OP的解决方案,但对于有类似需求但有许多Maven依赖关系的人来说,这是一个解决方案,

只需右键单击项目文件夹(在Eclipse中)并选择Export然后选择Java→ 可运行JAR将要求您选择JAR文件的位置最后,选择具有要运行的Main方法的类,并选择带有JAR文件的*Package依赖项,然后单击Finish

我尝试了多种解决方案,但这是一种在我们想要创建一个不可执行的胖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

要从命令行本身创建可执行JAR,只需从项目路径运行以下命令:

mvn assembly:assembly

这也是一种选择。您将能够构建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>