java.lang.NoClassDefFoundError: org/quartz/SchedulerFactory

java.lang.NoClassDefFoundError: org/quartz/SchedulerFactory

我正在使用 Java Quartz 库编写应用程序。

我的 pom.xml 有以下依赖项。

<dependencies>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.pranayhere</groupId>
            <artifactId>recurr</artifactId>
            <version>1.1.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.20</version>
        </dependency>
    </dependencies>

当我在 intellij 中 运行 时它工作,但当我 运行 使用时它不工作 java -jar target/application.jar

我收到以下错误:

java -jar target/test-rrule-quartz-1.0-SNAPSHOT.jar 
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: org/quartz/SchedulerFactory
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
        at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
        at java.lang.Class.getMethod0(Class.java:3018)
        at java.lang.Class.getMethod(Class.java:1784)
        at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: org.quartz.SchedulerFactory
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 7 more

如果需要任何额外信息,请告诉我。

您在 maven 中添加依赖项的事实仅意味着当您编译代码时,quartz 的 jar 位于类路径中。这意味着您可以在代码中使用该 jar 中的 classes/Interfaces。

但是,一旦 Maven 编译了您的代码并创建了 jar,您就有责任安排 "runtime"(您对 java -jar 所做的)。也就是说,您必须将石英罐添加到类路径中。 Maven 是一个构建框架,它不了解运行时。

有很多方法可以解决这个问题,仅举几例:

  1. 运行 带有 -cp 标志并将所有 jar 添加到类路径中。在这种情况下,您必须提供所有 jar 的路径,因此您可能希望将所有依赖项复制到某种 "lib" 文件夹中并与工件一起分发。这是完成这项工作的一种 "old-school" 方式。

  2. 使用 "Fat Jar"(如果您不熟悉这个概念,请参阅 here)这是 - "bake" 从依赖 jar 到您创建的一个罐子(在本例中为 test-rrule-quartz-1.0-SNAPSHOT.jar)。这样,结果 artifcat 会很大,但不需要其他依赖项。

  3. 更奇特但仍然很方便 - 使用 spring 引导,它已经在一个特殊插件的帮助下将所有内容包装到一个工件中。