我在独立应用程序中使用 Maven,并且我想将 JAR 文件中的所有依赖项打包到库文件夹中,如此处答案之一所述:
我希望我的最终 JAR 文件有一个库文件夹,其中包含 JAR 文件形式的依赖项,而不是像
maven-shade-plugin
将依赖项以文件夹形式(如 Maven 层次结构)放在 .m2 文件夹中。
嗯,实际上当前的配置满足了我的要求,但是我在运行应用程序时加载 JAR 文件时遇到问题。我无法加载课程。
这是我的配置:
<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.
如何解决此异常?
以下是我的解决方案。测试一下它是否适合您:
<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 文件中,并配置
Manifest.mf
文件。
但是随后您将需要添加自定义类加载代码来加载 JAR 文件。
或者,为了避免自定义类加载,您可以使用“${project.build.directory}/lib”,但在这种情况下,最终的 JAR 文件中没有依赖项,这就达不到目的。
距离提出这个问题已有两年了。尽管如此,嵌套 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>
最简单、最有效的方法是使用像这样的 uber 插件:
<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-${project.artifactId}-${project.version}</finalName>
</configuration>
</plugin>
您将在一个 JAR 文件中对所有内容进行非规范化。
截至 11/2023 的编辑:链接的插件不再维护,并且可能不适用于最新的 Java 或 Maven 版本。
可执行打包程序 maven 插件 正好可以用于此目的:创建包含所有依赖项作为特定文件夹中的 JAR 文件的独立 Java 应用程序。
只需将以下内容添加到
pom.xml
部分内的 <build><plugins>
(请务必相应地替换 mainClass
的值):
<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>
运行
target/<YourProjectAndVersion>-pkg.jar
后,构建的JAR文件位于mvn package
。它的所有编译时和运行时依赖项都将包含在 JAR 文件内的 lib/
文件夹中。
免责声明:我是该插件的作者。
我是这样做的:
<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,该参数也列出了所有依赖库。
整个文件位于目标文件夹内的 appasemly 文件夹中。史诗般的。
============== 是的,我知道这是一个旧线程,但它在搜索结果中的排名仍然很高,所以我认为它可能会对像我这样的人有所帮助。
这显然是一个类路径问题。请注意,当您在 IDE 之外运行程序时,类路径必须稍作更改。这是因为 IDE 加载相对于项目根文件夹的其他 JAR,而对于最终 JAR,情况通常并非如此。
在这些情况下我喜欢做的是手动构建 JAR。我最多花了5分钟,但总能解决问题。我不建议你这样做。找到一种使用Maven的方法,这就是它的目的。