简体   繁体   English

运行jar时出现ClassNotFoundException,但直接运行应用程序时则没有

[英]ClassNotFoundException when running a jar but not when running the app directly

My app is facing a NoClassDefFoundError when trying to access external dependencies, but only when run as a jar. 尝试访问外部依赖项时,我的应用程序遇到NoClassDefFoundError ,但仅在以jar运行时才遇到。

Using Intellij, I have a simple app with main class with some calls to external dependencies such as slf4j. 使用Intellij,我有一个具有主类的简单应用程序,对外部依赖项(例如slf4j)进行了一些调用。

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

} }

The pom.xml includes the relevant dependencies and the app is compiled successfully. pom.xml包含相关的依赖项,并且该应用程序已成功编译。

When running the app from the intellij as regular application it is running with no problem. 从intellij作为常规应用程序运行应用程序时,它运行正常。

But when creating an executable jar out of it and trying to run it, it crashes and can't find external dependencies: 但是,当用它创建可执行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

I added this to the pom to try to solve the problem, but it didn't help: 我将其添加到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>

The manifest file is located in src/main/resources/META-INF/MANIFEST.MF: 清单文件位于src / main / resources / META-INF / MANIFEST.MF中:

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

Your meta-inf should have following attributes Manifest-Version: 1.0 您的meta-inf应该具有以下Manifest-Version属性:1.0
Created-By: xxxx 创建者:xxxx
Main-Class: com.sample.Main 主要类别:com.sample.Main
ClassPath: path/to/jars/your.jar 类路径:path / to / jars / your.jar

java -cp yourpath/example.jar com.sample.Main java -cp yourpath / example.jar com.sample.Main
Or 要么
java -jar example.jar java -jar example.jar

It's simple to understand. 很容易理解。 The jar that you are creating contains only the .class files of your code, not of the other libraries that you're importing. 您正在创建的jar仅包含代码的.class文件,而不包含要导入的其他库的.class文件。 So when you run your code, it is unable to find the external library ( org.slf4j in this case) that you have referenced in your code. 因此,当您运行代码时,它无法找到您在代码中引用的外部库(在本例中为org.slf4j )。

I don't know about the maven jar plugin that you're using, but try the maven assembly plugin. 我不知道您正在使用的Maven jar插件,但是请尝试使用Maven程序集插件。 This plugin is used to bundle up all the other libraries that you use along with your code and create a "bundled" jar. 该插件用于捆绑您与代码一起使用的所有其他库,并创建一个“捆绑的” jar。 Add the following to your pom.xml . 将以下内容添加到pom.xml You can add this portion between <plugins> and </plugins> . 您可以在<plugins></plugins>之间添加此部分。

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

This additionally binds this "assembly" goal to the package phase of maven. 这另外将“组装”目标绑定到了Maven的package阶段。 So mvn package should create your jar. 所以mvn package应该创建您的jar。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM