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

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


当前回答

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

其他回答

对我有用的是:

  <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提供的代码,并进行了更改:

maven依赖插件在“准备包”阶段执行我将解压缩的类直接提取到“目标/类”

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

mvn assembly:assembly

对于任何想要从über 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程序集插件的配置,而是依赖项的属性。

这是我找到的最好的方法:

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

使用此配置,所有依赖项都将位于依赖项jar中。我的应用程序没有Main类,只有上下文类,但我的一个依赖项确实有一个Main类(com.myDomain.ec.MainClassName),它启动JMX服务器,并接收start或stop参数。因此,我可以这样启动我的应用程序:

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

将所有依赖项嵌入项目的JAR文件本身可能不是一个好主意。

我明白这一点(易于部署/使用),但这取决于您的项目的用例(可能还有其他选择(见下文))。

如果您完全独立使用,为什么不呢?

但是,如果您在其他上下文中使用项目(例如在web应用程序中,或放置在其他JAR所在的文件夹中),则类路径中可能有JAR副本(文件夹中的副本,JAR文件中的副本)。也许不是出价交易,但我通常避免这样做。

一个很好的选择:

将应用程序部署为ZIP或WAR文件:归档文件包含项目的JAR文件和所有依赖的JAR文件;使用动态类加载器机制(请参阅Spring Framework,或者您可以自己轻松完成)来拥有项目的单个入口点(要启动的单个类-请参阅另一个答案中的Manifest机制),它将(动态)向当前类路径添加所有其他需要的JAR文件。

像这样,最后只需要一个清单和一个“特殊的动态类加载器main”,您就可以开始您的项目:

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