Java jar在运行时找不到类

3

我在 IntelliJ ide 中创建了一个简单的 Java 程序。我使用了一些库,当我尝试将 jar 导出为 artifact 并从命令行运行时,会出现以下错误:

Exception in thread "main" java.lang.NoClassDefFoundError: com/google/common/util/concurrent/FutureCallback
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
        at java.lang.Class.getMethod0(Class.java:2856)
        at java.lang.Class.getMethod(Class.java:1668)
        at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:494)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:486)
Caused by: java.lang.ClassNotFoundException: com.google.common.util.concurrent.FutureCallback
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        ... 6 more

IntelliJ 中编译和运行程序非常顺利。

我的项目配置为 gradle 项目,并拥有以下的 build.gradle 文件:

group 'marianpavel.com'
version '1.0'

apply plugin: 'java'

sourceCompatibility = 1.5

repositories {
    mavenCentral()
    maven {
        url "http://repo.bastian-oppermann.de"
    }
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
    compile 'de.btobastian.javacord:javacord:2.0.11'
    compile 'ch.qos.logback:logback-classic:1.0.13'
    compile 'de.btobastian.sdcf4j:sdcf4j-core:1.0.2'
    compile 'de.btobastian.sdcf4j:sdcf4j-javacord:1.0.2'
    compile 'org.jsoup:jsoup:1.9.2'
}

我将以下步骤导出jar包:项目结构 -> 构件 -> Jar -> 从带有依赖项的模块中 -> 添加主源文件夹和所有库文件,添加清单和主类,然后导出jar包。
我已经试了几天想理解为什么它无法找到这个 class

堆栈跟踪显示您的类路径中没有guava。您是否尝试使用“-classpath”选项在运行时添加它? - francesco foresti
你的程序似乎依赖于那些库,也就是说,在尝试运行程序时,你必须将它们添加到类路径中。 - Jozef Chocholacek
1个回答

6
我认为你有一个误解。
你的项目由两个重要部分组成:
1. 你自己的代码 2. 你的代码使用的外部库
当你在IDE中运行你的项目,并且你的项目设置正确时,这两个部分都在你的类路径中。
但是,当你为你的项目创建一个JAR文件时,它非常依赖于你的设置。也就是说:"默认"情况下,为你的项目创建的JAR文件只包含第一部分,因为你不希望所有外部类都被添加到"你的" JAR 文件中。
所以,为了解决这个问题:当你想从命令行运行你的程序时,你需要把所有这些外部JAR文件也加入到你的类路径中!因为,如上所述:要运行,需要同时存在"1"和"2"部分在类路径中。
结论:你应该检查gradle为你创建的JAR文件中放了什么。我很确定:那个JAR文件只包含"1"。
(顺便说一句,这样做是可以的。虽然可以将所有内容打包成单个JAR文件,但这需要你自己处理。)

我把项目中使用的所有jar包放在一个单独的文件夹中,并将该文件夹用于类路径,这样可以吗?目前我的库jar包都在主jar包中。 - Marian Pavel
我不能告诉你什么是正确的;-) 你必须想清楚你想让你的JAR看起来像什么。我认为你甚至可以在你的JAR的META信息中包含对其他JAR的“依赖”。在这种情况下,你只需要在你的类路径中添加该目录;并在你自己的JAR中列出所有所需的JAR。或者,你必须在你的类路径中列出所有JAR文件名!换句话说:你想阅读gradle文档来弄清楚这个工具正在做什么;以及你如何影响它正在做什么! - GhostCat
您非常优秀先生 :) 我已经导出了目录中的所有jar文件,并手动将所有库添加到类路径中,现在jar文件可以正确运行。 - Marian Pavel
非常感谢。很高兴能够帮助! - GhostCat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接