使用Maven在jar中包含依赖项

rac*_*cer 329 java maven-2 packaging jar

有没有办法强制maven(2.0.9)在一个jar文件中包含所有依赖项?

我将一个项目构建到一个jar文件中.我希望将依赖项中的类复制到jar中.

更新:我知道我不能在jar文件中包含一个jar文件.我正在寻找一种方法来解压缩指定为依赖项的jar,并将类文件打包到我的jar中.

Joh*_*fer 460

您可以使用带有"jar-with-dependencies"描述符的maven-assembly插件来完成此操作.这是我们的一个pom.xml中的相关块,它执行此操作:

  <build>
    <plugins>
      <!-- any other plugins -->
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>
Run Code Online (Sandbox Code Playgroud)

  • 如果任何新的mvn人像我一样陷入困境,请将插件添加到<build>里面的<build>里面的<plugins>. (38认同)
  • "附加"目标已弃用.应该首选"single"或"directory-single"目标. (29认同)
  • `directory-single`现在也已弃用. (15认同)
  • 在官方[网站]上推荐使用_single_(http://maven.apache.org/plugins/maven-assembly-plugin/) (14认同)
  • @ Christian.tucker目标目录中有第二个jar,如下所示:**./ target/example-0.0.1-SNAPSHOT.jar**和**./ target/example-0.0.1-SNAPSHOT-jar-与-dependencies.jar** (7认同)
  • 如何避免在代码中包含未使用的库?我的仅使用SSJ的jar总计10 MB :( (2认同)
  • @DA为什么人们忽略了类似的相关(阅读:相关)细节,这超出了我的范围。 (2认同)
  • 只需在配置中添加一件事。您的主要课程信息。&lt;archive&gt; &lt;manifest&gt; &lt;mainClass&gt;完全限定的名称&lt;/ mainClass&gt; &lt;/ manifest&gt; &lt;/ archive&gt; (2认同)
  • 它工作,但我在目标目录中看到两个JAR:有和没有依赖.如何仅生成具有依赖项的JAR? (2认同)

Pas*_*ent 132

使用Maven 2,正确的方法是使用Maven2 Assembly Plugin,它具有用于此目的的预定义描述符文件,您可以在命令行上使用:

mvn assembly:assembly -DdescriptorId=jar-with-dependencies
Run Code Online (Sandbox Code Playgroud)

如果你想让这个jar可执行,只需添加要运行的主类到插件配置:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>my.package.to.my.MainClass</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>
Run Code Online (Sandbox Code Playgroud)

如果要将该程序集创建为正常构建过程的一部分,则应将单个目录单个目标(assembly目标应仅从命令行运行)绑定到生命周期阶段(package有意义),如下所示:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <execution>
      <id>create-my-bundle</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        ...
      </configuration>
    </execution>
  </executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)

调整configuration元素以满足您的需求(例如,使用清单说明的东西).

  • 它对我有用,但有一个任务.在构建之后,现在创建了两个罐子,其中一个是项目artifactid-version,另一个是artifactid-version-"jar-with-dependencies".但我想只建一个罐子.还有别的办法吗? (5认同)
  • @SouvikBhattacharya 将 `&lt;appendAssemblyId&gt;false&lt;/appendAssemblyId&gt;` 添加到 `maven-assemble-plugin` 配置中。 (5认同)

abd*_*iel 32

如果你想做一个可执行的jar文件,他们也需要设置主类.所以完整的配置应该是.

    <plugins>
            <plugin>
                 <artifactId>maven-assembly-plugin</artifactId>
                 <executions>
                     <execution>
                          <phase>package</phase>
                          <goals>
                              <goal>single</goal>
                          </goals>
                      </execution>
                  </executions>
                  <configuration>
                       <!-- ... -->
                       <archive>
                           <manifest>
                                 <mainClass>fully.qualified.MainClass</mainClass>
                           </manifest>
                       </archive>
                       <descriptorRefs>
                           <descriptorRef>jar-with-dependencies</descriptorRef>
                      </descriptorRefs>
                 </configuration>
         </plugin>
   </plugins>
Run Code Online (Sandbox Code Playgroud)

  • @Tina J,您可以在“&lt;configuration&gt;”标记内添加“&lt;appendAssemblyId&gt;false&lt;/appendAssemblyId&gt;”,以排除最终名称中的“-jar-with-dependencies”后缀。 (5认同)
  • 为什么jar的名称后面加上“ jar-with-dependencies”?任何解决方法? (2认同)

Tho*_*ung 18

阴影maven插件.它可用于打包和重命名依赖项(以省略类路径上的依赖性问题).

  • 如果您不喜欢jar-with-dependencies作为文件名的一部分。 (2认同)

las*_*tha 15

您可以使用<classifier>标记来使用新创建的jar .

<dependencies>
    <dependency>
        <groupId>your.group.id</groupId>
        <artifactId>your.artifact.id</artifactId>
        <version>1.0</version>
        <type>jar</type>
        <classifier>jar-with-dependencies</classifier>
    </dependency>
</dependencies>
Run Code Online (Sandbox Code Playgroud)


Rop*_*Rop 12

如果你(像我一样)不喜欢上面描述的jar-with-dependencies方法,我更喜欢的maven-solution是简单地构建一个WAR项目,即使它只是你正在构建的一个独立的java应用程序:

  1. 制作一个普通的maven jar项目,它将构建你的jar文件(没有依赖项).

  2. 另外,设置一个maven war-project(只有一个空的src/main/webapp/WEB-INF/web.xml文件,这将避免maven-build中的警告/错误),只有你的jar项目一个依赖项,并使你的jar项目成为<module>你的战争项目.(这个war-project只是将所有jar文件依赖项包装到zip文件中的简单技巧.)

  3. 构建war-project以生成war文件.

  4. 在部署步骤中,只需将.war文件重命名为*.zip并解压缩即可.

您现在应该有一个lib-directory(可以将它移动到您想要的位置)与您的jar以及运行应用程序所需的所有依赖项:

java -cp 'path/lib/*' MainClass
Run Code Online (Sandbox Code Playgroud)

(classpath中的通配符适用于Java-6或更高版本)

我认为这在maven中设置更简单(不需要使用程序集插件)并且还可以让您更清楚地了解应用程序结构(您将在普通视图中看到所有相关jar的版本号,以及避免将所有内容堵塞到一个jar文件中).


And*_*nti 10

http://fiji.sc/Uber-JAR提供了对替代方案的出色解释:

构建uber-JAR有三种常用方法:

  1. 无阴影.解压缩所有JAR文件,然后将它们重新打包到单个JAR中.
    • Pro:使用Java的默认类加载器.
    • Con:具有相同路径的多个JAR文件中存在的文件(例如,META-INF/services/javax.script.ScriptEngineFactory)将相互覆盖,从而导致错误行为.
    • 工具:Maven Assembly Plugin,Classworlds Uberjar
  2. 阴影.与无阴影相同,但重命名(即"阴影")所有依赖项的所有包.
    • Pro:使用Java的默认类加载器.避免一些(不是全部)依赖版本冲突.
    • Con:具有相同路径的多个JAR文件中存在的文件(例如,META-INF/services/javax.script.ScriptEngineFactory)将相互覆盖,从而导致错误行为.
    • 工具:Maven Shade插件
  3. JAR的JAR.最终的JAR文件包含嵌入的其他JAR文件.
    • 专业版:避免依赖版本冲突.保留所有资源文件.
    • Con:需要捆绑一个特殊的"bootstrap"类加载器,以使Java能够从包装的JAR文件中加载类.调试类加载器问题变得更加复杂.
    • 工具:Eclipse JAR文件导出器,One-JAR.

  • 对于服务而言,情况并非如此,shade 插件具有转换器,其中之一用于连接“META-INF/services”目录下的文件内容。更多信息在这里:https://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html (2认同)

Gla*_*ier 5

我关于 Eclipse Luna 和 m2eclipse 的最终解决方案:自定义类加载器(下载并添加到您的项目中,仅 5 个类): http: //git.eclipse.org/c/jdt/eclipse.jdt.ui.git/plain/org。 eclipse.jdt.ui/jar%20in%20jar%20loader/org/eclipse/jdt/internal/jarinjarloader/ ; 这个类加载器是最好的一罐类加载器,而且速度非常快;

<project.mainClass>org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader</project.mainClass> <project.realMainClass>my.Class</project.realMainClass>

在 JIJConstants 中编辑“Rsrc-Class-Path”到“Class-Path”
mvn clean dependency:copy-dependency 包
使用瘦类加载器在 lib 文件夹中创建一个具有依赖项的 jar

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.java</include>
                <include>**/*.properties</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/*</include>
            </includes>
            <targetPath>META-INF/</targetPath>
        </resource>
        <resource>
            <directory>${project.build.directory}/dependency/</directory>
            <includes>
                <include>*.jar</include>
            </includes>
            <targetPath>lib/</targetPath>
        </resource>
    </resources>
<pluginManagement>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>${project.mainClass}</mainClass>
                            <classpathPrefix>lib/</classpathPrefix>
                        </manifest>

                        <manifestEntries>
                            <Rsrc-Main-Class>${project.realMainClass}  </Rsrc-Main-Class>
                            <Class-Path>./</Class-Path>
                        </manifestEntries>

                    </archive>
                </configuration>
            </plugin>
<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
Run Code Online (Sandbox Code Playgroud)


小智 5

        <!-- Method 1 -->
        <!-- Copy dependency libraries jar files to a separated LIB folder -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <excludeTransitive>false</excludeTransitive> 
                <stripVersion>false</stripVersion>
            </configuration>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <!-- Add LIB folder to classPath -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                    </manifest>
                </archive>
            </configuration>
        </plugin>


        <!-- Method 2 -->
        <!-- Package all libraries classes into one runnable jar -->
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
            </configuration>
        </plugin>            
Run Code Online (Sandbox Code Playgroud)