首页 文章

使用Maven在jar中包含依赖项

提问于
浏览
276

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

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

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

13 回答

  • 13

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

    您可以使用带有“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>
    
  • 399

    使用Maven 2,正确的方法是使用Maven2 Assembly Plugin,它具有pre-defined descriptor file用于此目的,您可以在命令行上使用:

    mvn assembly:assembly -DdescriptorId=jar-with-dependencies
    

    如果你想让这个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>
    

    如果要将该程序集创建为正常构建过程的一部分,则应将singledirectory-single目标(仅应从命令行运行 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>
    

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

  • 0

    如果你想做一个可执行的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>
    
  • 9

    shade maven plugin . 它可用于 package and rename 依赖项(省略类路径上的依赖性问题) .

  • 0

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

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

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

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

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

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

    java -cp 'path/lib/*' MainClass
    

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

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

  • 1

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

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

  • 23

    我对Eclipse Luna和m2eclipse的最终解决方案:Custom Classloader(下载并添加到您的项目中,仅限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/;这个类加载器非常适合单jar类加载器并且速度非常快;

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

    在JIJConstants "Rsrc-Class-Path"中编辑为"Class-Path"
    mvn clean依赖:copy-dependencies包
    在lib文件夹中创建了一个带有瘦类加载器的jar的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>
    
  • 13
    <!-- 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>
    
  • 120

    将Maven放在一边,你可以将JAR库放在Main Jar中,但是你需要使用自己的类加载器 .

    检查这个项目:One-JAR link text

  • 4

    这篇文章可能有点旧,但我最近也有同样的问题 . John Stauffer提出的第一个解决方案很好,但是我在今年 Spring 天工作时遇到了一些问题 . Spring 天的依赖 - jar 我use有一些属性文件和xml-schemas声明,它们共享相同的路径和名称 . 虽然这些jar来自相同的版本,但jar-with-dependencies maven-goal用最后找到的文件覆盖了这些文件 .

    最后,应用程序无法启动,因为 spring jar 无法找到正确的属性文件 . 在这种情况下,Rop提出的解决方案已经解决了我的问题 .

    此后,Spring-boot项目现在也存在 . 通过提供一个重载包目标并提供自己的类加载器的maven目标,它有一种非常酷的方式来管理这个问题 . 见spring-boots Reference Guide

  • 11

    Have a look at this answer:

    我正在创建一个作为Java JAR文件运行的安装程序,它需要将WAR和JAR文件解压缩到安装目录中的适当位置 . 依赖插件可以在包阶段与复制目标一起使用,它将下载Maven存储库中的任何文件(包括WAR文件)并将它们写在您需要的地方 . 我将输出目录更改为$ / classes,然后最终结果是正常的JAR任务包含我的文件就好了 . 然后我可以提取它们并将它们写入安装目录 .

    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>getWar</id>
            <phase>package</phase>
            <goals>
                <goal>copy</goal>
            </goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>the.group.I.use</groupId>
                        <artifactId>MyServerServer</artifactId>
                        <version>${env.JAVA_SERVER_REL_VER}</version>
                        <type>war</type>
                        <destFileName>myWar.war</destFileName>
                    </artifactItem>
                </artifactItems>
                <outputDirectory>${project.build.directory}/classes</outputDirectory>
            </configuration>
        </execution>
    </executions>
    
  • 2

    谢谢我在POM.xml文件中添加了下面的代码片段并解决了Mp问题并创建了包含所有依赖jar的胖jar文件 .

    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>
    </plugins>
    

相关问题