如何使用 Maven 创建具有依赖项的可执行/可运行 JAR?

发布于 2024-07-14 04:23:06 字数 80 浏览 6 评论 0原文

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

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

I want to package my project in a single executable JAR for distribution.

How can I make a Maven project package all dependency JARs into my output JAR?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

樱花坊 2024-07-21 04:23:06
<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>
<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>

and you run it with

mvn clean compile assembly:single

Compile goal should be added before assembly:single or otherwise the code on your own project is not included.

See more details in comments.


Commonly this goal is tied to a build phase to execute automatically. This ensures the JAR is built when executing mvn install or performing a deployment/release.

<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>
趴在窗边数星星i 2024-07-21 04:23:06

您可以使用依赖插件在打包阶段之前在单独的目录中生成所有依赖项,然后将其包含在清单的类路径中:

<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${project.build.directory}/classes/lib code> 作为 OutputDirectory 将所有 JAR 文件集成到主 JAR 文件中,但随后您将需要添加自定义类加载代码来加载 JAR 文件。

You can use the dependency-plugin to generate all dependencies in a separate directory before the package phase and then include that in the classpath of the manifest:

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

Alternatively, use ${project.build.directory}/classes/lib as OutputDirectory to integrate all JAR files into the main JAR file, but then you will need to add custom classloading code to load the JAR files.

傻比既视感 2024-07-21 04:23:06

(GitHub)

注释

请参阅 executable-jar-with-maven- example 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-dependency.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-plugin

  • 优点
  • 缺点
    • 自 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 插件

<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


Quarkus Maven 插件

  • 优点
  • 缺点
<plugin>
  <groupId>io.quarkus.platform</groupId>
  <artifactId>quarkus-maven-plugin</artifactId>
  <extensions>true</extensions>
  <configuration>
    <skipOriginalJarRename>true</skipOriginalJarRename> <!-- keep the original jar without .origin -->
    <properties>
      <quarkus.native.container-build>false</quarkus.native.container-build>
      <quarkus.package.type>uber-jar</quarkus.package.type>
      <quarkus.package.main-class>${mainClass}</quarkus.package.main-class>
      <quarkus.package.output-directory>${project.build.directory}</quarkus.package.output-directory>
      <quarkus.package.runner-suffix>-quarkus</quarkus.package.runner-suffix>
    </properties>
  </configuration>
  <executions>
    <execution>
      <id>uber-jar</id>
      <phase>package</phase>
      <goals>
        <goal>build</goal>
      </goals>
    </execution>
  </executions>
</plugin>

您有 target/${project.bulid.finalName}-quarkus.jar。

See executable-jar-with-maven-example (GitHub)

Notes

Those pros and cons are provided by Stephan.


For Manual Deployment

  • Pros
  • Cons
    • Dependencies are out of the final jar.

Copy Dependencies to a specific directory

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

Make the JAR File Executable and Classpath Aware

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

At this point the JAR file is actually executable with external classpath elements.

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

Make Deployable Archives

The JAR file is only executable with the sibling ...lib/ directory. We need to make archives to deploy with the directory and its content.

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

Now you have target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz) which each contains the jar and lib/*.


Apache Maven Assembly Plugin

  • Pros
  • Cons
    • No class relocation support (use maven-shade-plugin if class relocation is needed).
<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>

You have target/${project.bulid.finalName}-jar-with-dependencies.jar.


Apache Maven Shade Plugin

  • Pros
  • Cons
<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>

You have target/${project.build.finalName}-shaded.jar.


onejar-maven-plugin

  • Pros
  • Cons
    • Not actively supported since 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 Plugin

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

You have target/${project.bulid.finalName}-spring-boot.jar.


Quarkus Maven Plugin

  • Pros
  • Cons
<plugin>
  <groupId>io.quarkus.platform</groupId>
  <artifactId>quarkus-maven-plugin</artifactId>
  <extensions>true</extensions>
  <configuration>
    <skipOriginalJarRename>true</skipOriginalJarRename> <!-- keep the original jar without .origin -->
    <properties>
      <quarkus.native.container-build>false</quarkus.native.container-build>
      <quarkus.package.type>uber-jar</quarkus.package.type>
      <quarkus.package.main-class>${mainClass}</quarkus.package.main-class>
      <quarkus.package.output-directory>${project.build.directory}</quarkus.package.output-directory>
      <quarkus.package.runner-suffix>-quarkus</quarkus.package.runner-suffix>
    </properties>
  </configuration>
  <executions>
    <execution>
      <id>uber-jar</id>
      <phase>package</phase>
      <goals>
        <goal>build</goal>
      </goals>
    </execution>
  </executions>
</plugin>

You have target/${project.bulid.finalName}-quarkus.jar.

平安喜乐 2024-07-21 04:23:06

采用IAdapter的答案 并重新格式化它,我们有:

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

Taking IAdapter's answer and reformatting it, we have:

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

Next, I would recommend making this a natural part of your build, rather than something to call explicitly. To make this a integral part of your build, add this plugin to your pom.xml and bind it to the package lifecycle event. However, a gotcha is that you need to call the assembly:single goal if putting this in your pom.xml, while you would call 'assembly:assembly' if executing it manually from the command line.

<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>
风柔一江水 2024-07-21 04:23:06

使用maven-shade-plugin将所有依赖项打包到一个 über-JAR 文件中。 它还可用于通过指定主类来构建可执行 JAR 文件。 在尝试使用maven-assemble和maven-jar之后,我发现这个插件最适合我的需求。

我发现这个插件特别有用,因为它合并特定文件的内容而不是覆盖它们。 当 JAR 文件中存在具有相同名称的资源文件并且插件尝试打包所有资源文件时,需要执行此操作。

请参阅下面的示例:

<plugins>
    <!-- This plugin provides the capability to package
         the artifact in an über-JAR file, 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 JAR files-->
                        <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>

Use the maven-shade-plugin to package all dependencies into one über-JAR file. It can also be used to build an executable JAR file by specifying the main class. After trying to use maven-assembly and maven-jar, I found that this plugin best suited my needs.

I found this plugin particularly useful as it merges the content of specific files instead of overwriting them. This is needed when there are resource files that are have the same name across the JAR files and the plugin tries to package all the resource files.

See the example below:

<plugins>
    <!-- This plugin provides the capability to package
         the artifact in an über-JAR file, 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 JAR files-->
                        <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>
请持续率性 2024-07-21 04:23:06

您可以使用 maven-shade 插件构建 über 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>

You can use the maven-shade plugin to build an über JAR file like below:

<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>
复古式 2024-07-21 04:23:06

我长期使用 Maven 程序集插件,但我找不到 “已添加,正在跳过”。 现在,我正在使用另一个插件 - 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>

I have long used the Maven assembly plugin, but I could not find a solution to the problem with "already added, skipping". Now, I'm using another plugin - onejar-maven-plugin. An example is below (mvn package builds the JAR file):

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

You need to add a repository for that plugin:

<pluginRepositories>
    <pluginRepository>
        <id>onejar-maven-plugin.googlecode.com</id>
        <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
    </pluginRepository>
</pluginRepositories>
如果没有你 2024-07-21 04:23:06

您可以将以下内容添加到您的 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 时检查它。依赖项.jar。

我使用 Apache Maven 3.0.3 对此进行了测试。

You can add the following to your pom.xml file:

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

Afterwards you have to switch via the console to the directory, where the pom.xml file is located. Then you have to execute mvn assembly:single and then your executable JAR file with dependencies will be hopefully build. You can check it when switching to the output (target) directory with cd ./target and starting your JAR with a command similar to java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar.

I tested this with Apache Maven 3.0.3.

世俗缘 2024-07-21 04:23:06

我仔细检查了每一个响应,希望制作一个包含所有依赖项的可执行 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

I went through every one of these responses looking to make a fat executable JAR file containing all dependencies and none of them worked right. The answer is the shade plugin, it’s very easy and straightforward.

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

Be aware that your dependencies need to have a scope of compile or runtime for this to work properly.

This example came from mkyong.com

生死何惧 2024-07-21 04:23:06

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

You can use maven-dependency-plugin, but the question was how to create an executable JAR file. To do that requires the following alteration to Matthew Franglen's response (btw, using the dependency plugin takes longer to build when starting from a clean target):

<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>
关于从前 2024-07-21 04:23:06

如果您确实想将其他 JAR 内容重新打包到单个生成的 JAR 中,则另一个选择是 Maven组装插件。 它解压所有内容,然后通过 true 将所有内容重新打包到目录中。 然后您将进行第二遍将其构建到一个巨大的 JAR 中。

另一个选项是 OneJar 插件。 这一步即可执行上述所有重新打包操作。

Another option if you really want to repackage the other JARs contents inside your single resultant JAR is the Maven Assembly plugin. It unpacks and then repacks everything into a directory via <unpack>true</unpack>. Then you'd have a second pass that built it into one massive JAR.

Another option is the OneJar plugin. This performs the above repackaging actions all in one step.

温暖的光 2024-07-21 04:23:06

您可以结合使用 maven-shade-pluginmaven-jar-plugin

  • maven-shade-plugin 将您的类和所有依赖项打包在一个 JAR 文件中。
  • 配置 maven-jar-plugin 以指定可执行 JAR 文件的主类(请参阅 设置类路径,“使 Jar 可执行”一章)。

maven-jar-pluginPOM 配置示例:

        <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

You could combine the maven-shade-plugin and maven-jar-plugin.

  • The maven-shade-plugin packs your classes and all dependencies in a single JAR file.
  • Configure the maven-jar-plugin to specify the main class of your executable JAR file (see Set Up The Classpath, chapter "Make The Jar Executable").

Example POM configuration for maven-jar-plugin:

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

Finally create the executable JAR file by invoking:

mvn clean package shade:shade
薔薇婲 2024-07-21 04:23:06

它的工作方式如下:

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

解包必须在生成资源阶段,否则不会作为资源包含在内。

It will work like:

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

Unpacking has to be in the generate-resources phase or it will not be included as resources.

新雨望断虹 2024-07-21 04:23:06

我认为刘肯说得对。 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>

Ken Liu has it right in my opinion. The Maven dependency plugin allows you to expand all the dependencies, which you can then treat as resources. This allows you to include them in the main artifact. The use of the assembly plugin creates a secondary artifact which can be difficult to modify - in my case I wanted to add custom manifest entries. My POM file ended up as:

<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>
痴梦一场 2024-07-21 04:23:06

为了解决这个问题,我们将使用 Maven Assembly 插件,它将 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

Maven - 将 JAR 文件及其依赖项 JAR 文件创建为单个可执行 JAR 文件

To resolve this issue, we will use the Maven Assembly plugin that will create the JAR file together with its dependency JAR files into a single executable JAR file. Just add the below plugin configuration in your pom.xml file.

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

After doing this, don’t forget to run the Maven tool with this command:

mvn clean compile assembly:single

Maven - Creating a JAR file together with its dependency JAR files into a single executable JAR file

橘虞初梦 2024-07-21 04:23:06

使用 maven- assembly-plugin-2.2.1 定位共享程序集文件有什么问题?

尝试使用descriptorId配置参数而不是descriptor/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>

What is the problem with locating shared assembly files with maven-assembly-plugin-2.2.1?

Try using the descriptorId configuration parameter instead of descriptors/descriptor or descriptorRefs/descriptorRef parameters.

Neither of them do what you need: look for the file on classpath.
Of course you need adding the package where the shared assembly resides on the maven-assembly-plugin's classpath (see below).
If you're using Maven 2.x (not Maven 3.x), you may need adding this dependency in top-most parent pom.xml in the pluginManagement section.

See this for more details.

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

Example:

<!-- 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>
夏有森光若流苏 2024-07-21 04:23:06

我比较了这篇文章中提到的树插件。 我生成了两个 JAR 文件和一个包含所有 JAR 文件的目录。 我比较了结果,绝对是 maven-shade-plugin 是最好的。

我的挑战是我有多个需要合并的 Spring 资源以及 jax- rs 和 JDBC 服务。 与maven-assemble-plugin相比,它们都被shade插件正确合并了。 在这种情况下,除非您将它们复制到您自己的资源文件夹中并手动合并一次,否则 Spring 将失败。

两个插件都输出正确的依赖树。 我有多个范围,如测试、提供、编译等。两个插件都跳过了测试和提供。 他们都生成了相同的清单,但我能够使用他们的变压器将许可证与阴影插件合并。
使用maven-dependency-plugin当然不会遇到这些问题,因为 JAR 文件不会被提取。 但正如其他人指出的那样,您需要携带一个额外的文件才能正常工作。

以下是 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>

I compared the tree plugins mentioned in this post. I generated two JAR files and a directory with all the JAR files. I compared the results and definitely the maven-shade-plugin is the best.

My challenge was that I have multiple Spring resources that needed to be merged, as well as jax-rs, and JDBC services. They were all merged properly by the shade plugin in comparison with the maven-assembly-plugin. In which case Spring will fail unless you copy them to your own resources folder and merge them manually one time.

Both plugins output the correct dependency tree. I had multiple scopes like test, provide, compile, etc. The test and provided were skipped by both plugins. They both produced the same manifest, but I was able to consolidate licenses with the shade plugin using their transformer.
With the maven-dependency-plugin of course you don't have those problems, because the JAR files are not extracted. But like some other have pointed out, you need to carry one extra file(s) to work properly.

Here is a snip of the pom.xml file:

<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>
·深蓝 2024-07-21 04:23:06

对于任何寻找从 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 的配置,而是依赖项的属性。

For anyone looking for options to exclude specific dependencies from the über JAR file, this is a solution that worked for me:

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

It's not a configuration of the mvn-assembly-plugin, but a property of the dependency.

谷夏 2024-07-21 04:23:06

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

我明白这一点(易于部署/使用),但这取决于您项目的用例(并且可能有替代方案(见下文))。

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

但是,如果您在其他上下文中使用您的项目(例如在 Web 应用程序中,或者放入其他 JAR 所在的文件夹中),则您的类路径中可能会有 JAR 重复项(文件夹中的 JAR、JAR 文件中的 JAR) 。 也许不是投标交易,但我通常会避免这种情况。

一个不错的选择:

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

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

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

It may not be a good idea to embed all the dependencies in the project's JAR file itself.

I see the point (ease of deployment / usage), but it depends of the use case of your project (and there may be alternatives (see below)).

If you use it fully standalone, why not?

But if you use your project in other contexts (like in a web application, or dropped in a folder where other JARs are sitting), you may have JAR duplicates in your classpath (the ones in the folder, the one in the JAR files). Maybe not a bid deal, but I usually avoid this.

A good alternative:

  • deploy your application as a ZIP or WAR file: the archive contains your project's JAR file and all dependent JAR files;
  • use a dynamic classloader mechanism (see Spring Framework, or you can easily do this yourself) to have a single entry point of your project (a single class to start - see the Manifest mechanism in another answer), which will add (dynamically) to the current classpath all the other needed JAR files.

Like this, with in the end just a manifest and a "special dynamic classloader main", you can start your project with:

java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
○闲身 2024-07-21 04:23:06

对我有用的是:

  <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 在“准备包”阶段执行
  2. 我直接提取解压的类到“目标/类别”

Something that has worked for me was:

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

I had an extraordinary case, because my dependency was system one:

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

I have changed the code provided by user189057 with changes:

  1. maven-dependency-plugin is executed in "prepare-package" phase
  2. I am extracting unpacked classes directly to "target/classes"
女中豪杰 2024-07-21 04:23:06

这是我发现的最好方法:

<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

This is the best way I found:

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

With this configuration, all dependencies will be located in /dependency-jars. My application has no Main class, just context ones, but one of my dependencies do have a Main class (com.myDomain.etc.MainClassName) that starts the JMX server, and receives a start or a stop parameter. So with this I was able to start my application like this:

java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start
一杆小烟枪 2024-07-21 04:23:06

已经有数百万个答案。 我想补充一点,如果您不需要向应用程序添加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/

There are millions of answers already. I wanted to add you don't need <mainClass> if you don't need to add entryPoint to your application. For example, APIs may not have necessarily have a main method.

Maven plugin configuration

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

Build

mvn clean compile assembly:single

Verify

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/
格子衫的從容 2024-07-21 04:23:06

我想将我的 Spring 应用程序(使用 Apereo Foundation 的 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>

而我的Application是:

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);
            }
        };
    }

}

I wanted to migrate my Spring application (using Apereo Foundation's CAS client) to Spring Boot 1.5. I ran into many problems, like:

no main manifest attribute, in target/cas-client-web.jar

I tried to make one unique JAR file with all dependencies. After searching on the Internet, I was able to do it with these lines:

<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 is my main class:

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

And my Application is:

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);
            }
        };
    }

}
永不分离 2024-07-21 04:23:06

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

mvn assembly:assembly

To create an executable JAR from the command line itself, just run the below command from the project path:

mvn assembly:assembly
人海汹涌 2024-07-21 04:23:06

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

我有一个与 OP 类似的要求,只是我的项目有太多(Maven)依赖项。 幸运的是,唯一对我有用的解决方案是使用 Eclipse。 它非常简单,也非常直接。 这不是 OP 的解决方案,但它是为具有类似需求但具有许多 Maven 依赖项的人提供的解决方案,

  1. 只需右键单击项目文件夹(在 Eclipse 中)并选择导出< /em>


  2. 然后选择JavaRunnable JAR

  3. 系统将要求您选择 JAR 文件的位置

  4. 最后,选择具有要运行的 Main 方法的类,然后选择 *Package dependency with the JAR file 并单击 >完成

I tried the most upvoted answer here and was able to get the JAR file runnable. But the program didn't run correctly. I do not know what the reason was. When I try to run from Eclipse, I get a different result, but when I run the JAR file from command line I get a different result (it crashes with a program-specific runtime error).

I had a similar requirement as the OP just that I had too many (Maven) dependencies for my project. Fortunately, the only solution that worked for me was that using Eclipse. It is very simple and very straightforward. This is not a solution for the OP, but it is a solution for someone who has a similar requirement, but with many Maven dependencies,

  1. Just right-click on your project folder (in Eclipse) and select Export

  2. Then select JavaRunnable JAR

  3. You will be asked to choose the location of the JAR file

  4. Finally, select the class that has the Main method that you want to run and choose *Package dependencies with the JAR file and click Finish

天邊彩虹 2024-07-21 04:23:06

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

This could also be an option. You will be able to build your JAR file.

<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>
最美的太阳 2024-07-21 04:23:06

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

Add to file pom.xml:

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

And

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

That’s it. Next, the mvn package will also create one fat JAR additionally, including all dependency JAR files.

仅一夜美梦 2024-07-21 04:23:06

maven-assemble-plugin 对我来说非常有用。

我花了几个小时使用 maven-dependency-plugin,但无法让它工作。 主要原因是我必须在配置部分中显式定义工件项,应将其包含在内,如 文档

当您想要使用它时,有一个示例:mvn dependency:copy,其中不包含任何artifactItems,但它不起作用。

The maven-assembly-plugin worked great for me.

I spent hours with the maven-dependency-plugin and couldn't make it work. The main reason was that I had to define the artifact items explicitly in the configuration section which should be included as it is described in the documentation.

There is an example there for the cases when you want to use it like: mvn dependency:copy, where there are not included any artifactItems, but it doesn't work.

各自安好 2024-07-21 04:23:06

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

构建 fat JAR 文件所需运行的命令:

mvn assembly:assembly

I tried multiple solutions, but this is the one that worked perfectly in the scenario where we wanted to create a non-executable fat JAR file with all internal dependencies for external systems having no previous relevance. A production scenario was tested.

Include this in the pom.xml file:

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

The command to run to build the fat JAR file:

mvn assembly:assembly
意犹 2024-07-21 04:23:06

这篇博文展示了另一种结合 maven-jar 和 maven-assemble 插件的方法。 使用博客文章中的程序集配置 XML 文件,还可以控制是否扩展依赖项或仅将其收集在文件夹中并由清单中的类路径条目引用:

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

确切地说,这里描述的是:使用 Maven 的具有依赖 JAR 文件的可执行 JAR 文件

This blog post shows another approach with combining the maven-jar and maven-assembly plugins. With the assembly configuration XML file from the blog post it can also be controlled if dependencies will be expanded or just be collected in a folder and referenced by a classpath entry in the manifest:

The ideal solution is to include the jars in a lib folder and the manifest.mf file of the main jar include all the jars in classpath.

And exactly that one is described here: Executable JAR file with dependent JAR files using Maven

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文