如何使用Maven将所有必需的JAR文件放在最终JAR文件的库文件夹中?

我在独立应用程序中使用Maven,并且想要将所有依赖关系打包到库文件夹中的JAR文件中,如其中一个答案中所述:

我怎样才能创build一个使用Maven的依赖关系的可执行JAR?

我希望我的最终JAR文件有一个包含依赖关系作为JAR文件的库文件夹,而不是像Maven层次结构一样在.m2文件夹中放置依赖关系的maven-shade-plugin

那么,实际上当前的configuration做我想要的,但我在运行应用程序时加载JAR文件有问题。 我无法加载类。

这是我的configuration:

 <plugins> <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}/classes/lib</outputDirectory> <overWriteReleases>false</overWriteReleases> <overWriteSnapshots>false</overWriteSnapshots> <overWriteIfNewer>true</overWriteIfNewer> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>com.myapp.MainClass</mainClass> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>install</id> <phase>install</phase> <goals> <goal>sources</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.5</version> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> 

该项目从Eclipse运行良好,JAR文件放在我的最终JAR文件中的库文件夹,但从目标文件夹运行最终的JAR文件时,我总是得到ClassNotFoundException

 Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext Caused by: java.lang.ClassNotFoundException: org.springframework.context.ApplicationContext at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) Could not find the main class: com.myapp.MainClass. Program will exit. 

我如何解决这个exception?

以下是我的解决scheme。 testing它是否适合你:

 <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}/classes/lib</outputDirectory> <overWriteReleases>false</overWriteReleases> <overWriteSnapshots>false</overWriteSnapshots> <overWriteIfNewer>true</overWriteIfNewer> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <!-- <classpathPrefix>lib</classpathPrefix> --> <!-- <mainClass>test.org.Cliente</mainClass> --> </manifest> <manifestEntries> <Class-Path>lib/</Class-Path> </manifestEntries> </archive> </configuration> </plugin> 

第一个插件将所有依赖项放在target / classes / lib文件夹中,第二个插件包含最终JAR文件中的库文件夹,并configurationManifest.mf文件。

但是,您将需要添加自定义类加载代码来加载JAR文件。

或者,为了避免自定义类加载,可以使用“$ {project.build.directory} / lib”,但是在这种情况下,最终的JAR文件中没有依赖关系,这就违背了目的。

这个问题问了两年了。 尽pipe如此,嵌套JAR文件仍然存在。 我希望它能帮助别人。

更新:

 <build> <plugins> <plugin> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <phase>install</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build> 

最简单和最有效的方法是使用这样一个超级插件:

  <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> <configuration> <finalName>uber-${artifactId}-${version}</finalName> </configuration> </plugin> 

您将在一个JAR文件中将所有内容解除归一化。

可执行的打包程序maven插件可以用于这个目的:创build包含所有依赖关系的独立Java应用程序作为特定文件夹中的JAR文件。

只需在<build><plugins>部分的内部添加以下内容到你的pom.xml (确保相应地replacemainClass的值):

 <plugin> <groupId>de.ntcomputer</groupId> <artifactId>executable-packer-maven-plugin</artifactId> <version>1.0.1</version> <configuration> <mainClass>com.example.MyMainClass</mainClass> </configuration> <executions> <execution> <goals> <goal>pack-executable-jar</goal> </goals> </execution> </executions> </plugin> 

运行mvn package后,构build的JAR文件位于target/<YourProjectAndVersion>-pkg.jar 。 所有的编译时和运行时依赖都将被包含在JAR文件的lib/文件夹中。

免责声明:我是该插件的作者。

以下链接:

如何:Eclipse的Maven安装与依赖关系的构buildjar

我发现这不是可行的解决scheme,因为类加载器不会从jar文件中加载jar文件,所以我认为我会解压jar文件中的依赖文件。

以下是我如何做到的:

  <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.2</version> <configuration> <appendAssemblyId>false</appendAssemblyId> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>com.project.MainClass</mainClass> </manifest> </archive> </configuration> </plugin> 

然后我只是运行:

 mvn assembly:assembly 

我发现这个问题的答案是:

http://padcom13.blogspot.co.uk/2011/10/creating-standalone-applications-with.html

你不但可以在lib文件夹中获得相关的lib文件,还可以得到一个同时具有unix和dos可执行文件的bin目录。

可执行程序最终会使用-cp参数调用java,该参数也列出了所有依赖的库。

整个批次都位于目标文件夹内的一个assembly文件夹中。 史诗。

=============是的,我知道这是一个古老的线索,但search结果仍然很高,所以我认为这可能会帮助像我这样的人。

这显然是一个类path问题。 考虑到在IDE之外运行程序时,类path必须更改一些。 这是因为IDE将加载其他JAR相对于项目的根文件夹,而在最终JAR的情况下,这通常是不正确的。

我喜欢在这些情况下做的是手动构buildJAR。 这最多需要5分钟,而且总是能解决问题。 我不build议你这样做。 find一个使用Maven的方法,这是它的目的。