有没有办法强制maven(2.0.9)将所有依赖项包含在一个jar文件中?
我有一个项目的构建到一个单一的jar文件。我希望依赖的类也能复制到jar中。
更新:我知道我不能只在jar文件中包含一个jar文件。我正在寻找一种方法来解包指定为依赖项的jar,并将类文件打包到我的jar中。
有没有办法强制maven(2.0.9)将所有依赖项包含在一个jar文件中?
我有一个项目的构建到一个单一的jar文件。我希望依赖的类也能复制到jar中。
更新:我知道我不能只在jar文件中包含一个jar文件。我正在寻找一种方法来解包指定为依赖项的jar,并将类文件打包到我的jar中。
当前回答
这是maven插件。它可用于打包和重命名依赖项(以忽略类路径上的依赖项问题)。
其他回答
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.
把Maven放在一边,您可以把JAR库放在Main JAR中,但是您需要使用自己的类加载器。
检查这个项目:One-JAR链接文本
您可以使用<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>
你可以使用带有"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>
如果你(像我一样)不是特别喜欢上面描述的带依赖的罐子方法, 我更喜欢的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文件中)。