如何 运行 一个包含依赖库的 jar?

How to run a jar which contains dependency libraries within it?

我有一个 Maven 生成的 jar,其中包含所有依赖 jar,位于名为 lib.

的目录中
app-0.0.1-SNAPSHOT.jar
|_ lib/
|_ app.properties
|_ app/
|_ spring/

但是,当我从命令行使用 运行 它时:

java -jar app-0.0.1-SNAPSHOT.jar

它抱怨找不到 slf4j(实际上它包含在目录 lib 中)。基本上,它无法识别 lib 目录。

这个 jar 是使用 maven-dependency-pluginmaven-jar-plugin 根据 this solution.正如解决方案所建议的那样,需要自定义 class 加载代码来加载 jars。我想知道这个 class 加载代码应该是什么样子。

Manifest.mf

Manifest-Version: 1.0
Built-By: me
Build-Jdk: 1.6.0_26
Class-Path: lib/camel-core-2.6.0.jar lib/commons-logging-api-1.1.jar ...
Created-By: Apache Maven 3.1.1
Main-Class: app.Main
Archiver-Version: Plexus Archiver

在答案中显示这一点可能比大量评论更容易...

您有两种选择来完成您想要的:

  1. 创建一个 jar 文件,将 所有 依赖项打包到
  2. 创建一个独立的 jar,它只包含工件的资源和 classes,但不包含依赖项。依赖的 jar 放在某个目录中,与 jar 一起。

要执行 #1,您可以使用 maven-assembly-plugin 构建一个包含所有依赖项的 jar 文件,在您的 POM 中使用以下内容:

<plugin>
     <artifactId>maven-assembly-plugin</artifactId>
     <configuration>
          <descriptorRefs>
               <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          <archive>
               <manifest>
                    <mainClass>${main.class}</mainClass>
               </manifest>
          </archive>
     </configuration>
     <executions>
          <execution>
               <phase>package</phase>
               <goals>
                    <goal>single</goal>
               </goals>
          </execution>
     </executions>
</plugin>

此 jar 中的清单如下所示:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: <username>
Build-Jdk: 1.7.0_60
Main-Class: your.main.Class

有了这个解决方案,你的 class 路径上就不需要一堆罐子了,因为它们已经 罐子里,在它们正确的包位置 (采用 .class 格式)

如果你选择#2,解决方案应该为你提供这样的东西(假设你的所有依赖项都在 target 目录

中名为 lib 的目录中
your.artifact.jar
lib
  |-- dependent jars...

您的 jar 清单将包含:

Manifest-Version: 1.0
Built-By: me
Build-Jdk: 1.6.0_26
Class-Path: lib/camel-core-2.6.0.jar lib/commons-logging-api-1.1.jar ...
Created-By: Apache Maven 3.1.1
Main-Class: app.Main
Archiver-Version: Plexus Archiver

请注意,lib 目录并未打包在 您的 jar 中,而是与它一起打包(即,您自己将它们一起分发)