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

我在自己的绿色软体中使用了 Maven,我想把 JAR 文件中的所有依赖项打包到一个库文件夹中,正如这里的一个答案所提到的:

如何使用 Maven 创建具有依赖项的可执行 JAR?

I want my final JAR file to have a library folder that contains the dependencies as JAR files, not like what the maven-shade-plugin that puts the dependencies in the form of folders like the Maven hierarchy in the .m2 folder.

Well, actually the current configuration does what I want, but I am having a problem with loading the JAR files when running the application. I can't load the classes.

这是我的配置:

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

我如何修复这个异常?

256430 次浏览

这显然是一个类路径问题。请注意,当您在 IDE 之外运行程序时,类路径必须稍作更改。这是因为 IDE 相对于项目的根文件夹加载其他 JAR,而对于最终的 JAR,这通常是不正确的。

在这些情况下,我喜欢手动构建 JAR。它最多花费我5分钟,它总能解决问题。我不建议你这么做。想办法利用玛文,这就是它的作用。

最简单也是最有效的方法是使用这样一个优步插件:

          <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 文件中对所有内容进行反规范化。

我是这么做的:

    <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

更新:

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

以下连结载有:

如何: Eclipse Maven 安装带依赖项的 build jar

我发现这是不可行的解决方案,因为类装入器不从 jar 中装入 jar,所以我认为我将解包 jar 中的依赖项。

以下是我的解决方案。如果它对你有效,请测试它:

<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 文件的问题仍然存在。我希望能帮到别人。

我找到了这个问题的答案:

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

您不仅可以获得 lib 文件夹中的依赖 lib 文件,还可以获得具有 unix 和 dos 可执行文件的 bin 控制器。

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

所有的东西都放在目标文件夹里的一个装配文件夹里。

============= 是的,我知道这是一个老主题,但它仍然在搜索结果中排名靠前,所以我想它可能会帮助像我这样的人。

executable packer maven plugin可以完全用于这个目的: 创建包含特定文件夹中的所有依赖项作为 JAR 文件的独立 Java 应用程序。

只需要在 <build><plugins>部分的 pom.xml中添加以下内容(确保相应地替换 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>

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

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