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

我有一个项目的构建到一个单一的jar文件。我希望依赖的类也能复制到jar中。

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


当前回答

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

其他回答

http://fiji.sc/Uber-JAR提供了一个很好的解释:

There are three common methods for constructing an uber-JAR: Unshaded. Unpack all JAR files, then repack them into a single JAR. Pro: Works with Java's default class loader. Con: Files present in multiple JAR files with the same path (e.g., META-INF/services/javax.script.ScriptEngineFactory) will overwrite one another, resulting in faulty behavior. Tools: Maven Assembly Plugin, Classworlds Uberjar Shaded. Same as unshaded, but rename (i.e., "shade") all packages of all dependencies. Pro: Works with Java's default class loader. Avoids some (not all) dependency version clashes. Con: Files present in multiple JAR files with the same path (e.g., META-INF/services/javax.script.ScriptEngineFactory) will overwrite one another, resulting in faulty behavior. Tools: Maven Shade Plugin JAR of JARs. The final JAR file contains the other JAR files embedded within. Pro: Avoids dependency version clashes. All resource files are preserved. Con: Needs to bundle a special "bootstrap" classloader to enable Java to load classes from the wrapped JAR files. Debugging class loader issues becomes more complex. Tools: Eclipse JAR File Exporter, One-JAR.

在Maven2中,正确的方法是使用Maven2 Assembly Plugin,它有一个预定义的描述符文件,你可以在命令行中使用:

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>

如果你想要创建程序集作为正常构建过程的一部分,你应该将单个或单目录目标(程序集目标应该只从命令行运行)绑定到生命周期阶段(包是有意义的),就像这样:

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

调整配置元素以满足您的需求(例如使用清单内容)。

我发现这是最明确的答案;这里的其他答案是缺少一些对我来说不明显的东西,例如MVN清洁包命令,以及单独添加插件作为依赖项。所有这些对于更习惯的专业用户来说可能是显而易见的。

https://howtodoinjava.com/maven/executable-jar-with-dependencies/

如果你(像我一样)不是特别喜欢上面描述的带依赖的罐子方法, 我更喜欢的maven解决方案是简单地建立一个war项目, 即使你只是在构建一个独立的Java应用程序:

Make a normal maven jar-project, that will build your jar-file (without the dependencies). Also, setup a maven war-project (with only an empty src/main/webapp/WEB-INF/web.xml file, which will avoid a warning/error in the maven-build), that only has your jar-project as a dependency, and make your jar-project a <module> under your war-project. (This war-project is only a simple trick to wrap all your jar-file dependencies into a zip-file.) Build the war-project to produce the war-file. In the deployment-step, simply rename your .war-file to *.zip and unzip it.

你现在应该有一个lib目录(你可以移动到你想要的地方),里面有你的jar和运行应用程序所需的所有依赖项:

java -cp 'path/lib/*' MainClass

(类路径中的通配符在Java-6或更高版本中有效)

我认为这样在maven中设置起来更简单(不需要使用汇编插件),而且可以更清楚地看到应用程序结构(您将在普通视图中看到所有依赖jar的版本号,并避免将所有内容都塞进一个jar文件中)。

你可以使用带有"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>