【问题标题】:ClassNotFoundException when running a jar but not when running the app directly运行 jar 时出现 ClassNotFoundException 但直接运行应用程序时不会出现
【发布时间】:2018-04-03 12:21:37
【问题描述】:

我的应用在尝试访问外部依赖项时面临NoClassDefFoundError,但仅限于作为 jar 运行时。

使用 Intellij,我有一个带有主类的简单应用程序,其中调用了一些外部依赖项,例如 slf4j。

public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
     ///
    public static void main(String[] args) {
    logger.debug("start");
    }

}

pom.xml包含相关依赖,应用编译成功。

当从 intellij 将应用程序作为常规应用程序运行时,它运行没有问题。

但是当用它创建一个可执行的 jar 并尝试运行它时,它会崩溃并且找不到外部依赖项:

 java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
  at com.example.Main.<clinit>(Main.java:18)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more
Exception in thread "main" 
Process finished with exit code 1

我将此添加到 pom 以尝试解决问题,但没有帮助:

    <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <!-- Build an executable JAR -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.0.2</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>com.example.Main</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

清单文件位于 src/main/resources/META-INF/MANIFEST.MF:

Manifest-Version: 1.0
Main-Class: com.example.Main

【问题讨论】:

  • 依赖项可能不包含在 jar 中。见stackoverflow.com/questions/574594/…
  • 你应该在构建路径中添加 slf4j jar,同时在 IDE 中运行 jar,IDE 会自动管理构建路径并在 pom.xml 中添加依赖声明。 @riorio

标签: java jar


【解决方案1】:

这很容易理解。您正在创建的 jar 仅包含您的代码的 .class 文件,而不包含您正在导入的其他库。因此,当您运行代码时,它无法找到您在代码中引用的外部库(在本例中为 org.slf4j)。

我不知道您正在使用的 maven jar 插件,但请尝试使用 maven 程序集插件。该插件用于捆绑您与代码一起使用的所有其他库,并创建一个“捆绑的”jar。将以下内容添加到您的 pom.xml。您可以在&lt;plugins&gt;&lt;/plugins&gt; 之间添加此部分。

<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
    <executions>
      <execution>
        <id>example</id>
        <configuration>
          <archive>
            <manifest>
              <mainClass>com.example.Main</mainClass>
            </manifest>
          </archive>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          <appendAssemblyId>false</appendAssemblyId>
        </configuration>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
</plugin>

这另外将这个“组装”目标绑定到 maven 的 package 阶段。所以mvn package 应该创建你的 jar。

【讨论】:

    【解决方案2】:

    您的 meta-inf 应具有以下属性 清单版本:1.0
    创建者:xxxx
    主类:com.sample.Main
    类路径:path/to/jars/your.jar

    java -cp yourpath/example.jar com.sample.Main
    或者
    java -jar 示例.jar

    【讨论】:

      猜你喜欢
      • 2014-07-21
      • 1970-01-01
      • 2013-04-26
      • 1970-01-01
      • 2022-08-19
      • 2018-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多