如何使用maven创建具有依赖关系的可执行jar?

jogvjijk  于 2021-06-30  发布在  Java
关注(0)|答案(21)|浏览(482)

我想将我的项目打包在一个可执行jar中进行分发。
如何让maven项目将所有依赖jar打包到输出jar中?

uplii1fm

uplii1fm1#

我查看了所有这些响应,希望生成一个包含所有依赖项的胖可执行jar,但没有一个是正确的。答案是shade插件,它非常简单明了。

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

请注意,您的依赖项需要有一个compile或runtime的范围才能正常工作。
这个例子来自mkyong.com

7rfyedvj

7rfyedvj2#

应该是这样的:

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

解包必须在生成资源阶段,因为如果在包阶段,将不会作为资源包含。试试干净的 Package ,你会看到的。

ufj5ltwl

ufj5ltwl3#

这是我发现的最好的方法:

<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服务器并接收 start 或者 stop 参数。因此,我可以这样启动我的应用程序:

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

我等着它对你们有用。

hxzsmxv2

hxzsmxv24#

我比较了本文中提到的树插件。我生成了2个jar和一个包含所有jar的目录。我比较了结果,肯定maven shade插件是最好的。我的挑战是,我有多个需要合并的spring资源,以及jax-rs和jdbc服务。与maven程序集插件相比,shade插件正确地合并了它们。在这种情况下,spring将失败,除非您将它们复制到自己的resources文件夹并手动合并一次。两个插件都输出正确的依赖关系树。我有多个作用域,比如test、provide、compile等,这两个插件都跳过了测试和提供。他们都出示了相同的舱单,但我

a0x5cqrl

a0x5cqrl5#

使用maven-assembly-plugin-2.2.1查找共享程序集文件时出现问题?
尝试使用descriptorid配置参数而不是descriptors/descriptor或descriptorrefs/descriptorref参数。
它们都不能满足您的需要:在类路径上查找文件。当然,您需要添加共享程序集驻留在maven程序集插件的类路径上的包(见下文)。如果您使用的是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>
j8ag8udp

j8ag8udp6#

你可以把 maven-shade-plugin 以及 maven-jar-plugin .
这个 maven-shade-plugin 将类和所有依赖项打包到一个jar文件中。
配置 maven-jar-plugin 指定可执行jar的主类(请参阅设置类路径,章节“使jar可执行”)。
的pom配置示例 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>

最后,通过调用以下命令创建可执行jar:

mvn clean package shade:shade
zour9fqk

zour9fqk7#

<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 or 否则,您自己的项目上的代码将不包括在内。
请参阅评论中的更多详细信息。
通常,这个目标与自动执行的构建阶段相关联。这样可以确保在执行时构建jar mvn install 或执行部署/释放。

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

wvyml7n58#

为了解决这个问题,我们将使用maven程序集插件,它将把jar及其依赖项jar一起创建到一个可执行jar文件中。只需在pom.xml文件中添加以下插件配置。

<build>
   <pluginManagement>
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
               <archive>
                  <manifest>
                     <addClasspath>true</addClasspath>
                     <mainClass>com.your.package.MainClass</mainClass>
                  </manifest>
               </archive>
               <descriptorRefs>
                  <descriptorRef>jar-with-dependencies</descriptorRef>
               </descriptorRefs>
            </configuration>
            <executions>
               <execution>
                  <id>make-my-jar-with-dependencies</id>
                  <phase>package</phase>
                  <goals>
                     <goal>single</goal>
                  </goals>
               </execution>
            </executions>
         </plugin>
      </plugins>
   </pluginManagement>
</build>

完成此操作后,不要忘记使用以下命令运行maven工具mvn clean compileassembly:single
http://jkoder.com/maven-creating-a-jar-together-with-its-dependency-jars-into-a-single-executable-jar-file/

flvlnr44

flvlnr449#

长期使用maven汇编插件,但我找不到解决问题的方法 "already added, skipping" . 现在,我正在使用另一个插件-onejar maven插件。下面的例子( 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>
xv8emn3q

xv8emn3q10#

我在博客上写了一些不同的方法。
参见可执行jar和maven示例(github)

注意事项

这些优点和缺点是由斯蒂芬提供的。

用于手动部署

赞成的意见
欺骗
依赖项已超出最终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) 每个都包含 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.bulid.finalName}-jar-with-dependencies.jar .

apache maven shade插件

赞成的意见
欺骗

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <shadedArtifactAttached>true</shadedArtifactAttached>
        <transformers>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>${fully.qualified.main.class}</mainClass>
          </transformer>
        </transformers>
      </configuration>
    </execution>
  </executions>
</plugin>

你有 target/${project.build.finalName}-shaded.jar .

onejar 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引导相关类。

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

x9ybnkn6

x9ybnkn611#

您可以将以下内容添加到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所在的目录。然后你必须执行mvnassembly:single and 然后您的可执行jar文件与依赖关系将有望建立。当您使用cd./target切换到output(target)目录并使用类似于java-jarmavenproject1-1.0-snapshot-jar-with-dependencies.jar的命令启动jar时,您可以检查它。
我用ApacheMaven3.0.3测试了这个。

v2g6jxz6

v2g6jxz612#

您可以使用maven shade插件构建一个uber jar,如下所示

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
        </execution>
    </executions>
</plugin>
u1ehiz5o

u1ehiz5o13#

如果您真的想重新打包单个结果jar中的其他jar内容,另一个选择是maven程序集插件。它解包,然后通过 <unpack>true</unpack> . 然后你会有第二次机会把它装进一个巨大的jar里。
另一个选择是onejar插件。这将在一个步骤中执行上述重新打包操作。

eivgtgni

eivgtgni14#

对我有用的是:

<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依赖插件在“prepare package”阶段执行2)我将解包类直接解压到“target/classes”

0wi1tuuw

0wi1tuuw15#

刘肯在我看来是对的。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>

相关问题