【问题标题】:Application built with Gradle starts successfully from IDE, but not from console使用 Gradle 构建的应用程序从 IDE 成功启动,但不能从控制台启动
【发布时间】:2017-06-04 19:19:13
【问题描述】:

我正在努力解决相当简单的问题,但无处可寻。 关键是 - 最近我开始学习 Gradle,并决定使用这个构建工具创建我的第一个 Intellij 项目。我使用 build.gradle 中定义的外部库:

group 'ant.rozanski'
version '1.0-SNAPSHOT'

apply plugin: 'java'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.fasterxml.jackson.core:jackson-databind:2.2.3'
        classpath 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.3.0'
    }
}
dependencies {
    testCompile 'org.junit.jupiter:junit-jupiter-api:5.0.0-M3'
    compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.3.0'
    compile 'com.fasterxml.jackson.core:jackson-databind:2.2.3'

    compile 'org.apache.commons:commons-lang3:3.4'
}

项目从 Intellij 'Run' 命令开始就好了。但是,不幸的是,当我尝试从控制台运行它时,我收到了这个异常:

Exception in thread "main" java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonFactory
    at model.AALJourney.setParams(AALJourney.java:40)
    at model.AALJourney.doJob(AALJourney.java:24)
    at Start.main(Start.java:11)
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.core.JsonFactory
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 3 more

看起来 gradle 没有将这些外部库放在类路径上。为什么?我该如何解决这个问题?

【问题讨论】:

    标签: java intellij-idea gradle console


    【解决方案1】:

    你应该使用 Gradle 的 application 插件。它提供了一个run 任务,该任务正确设置了类路径,还提供了使用 Windows 和 *nix 启动脚本构建可分发包的任务,这些脚本根据需要设置了类路径。

    除此之外,如果您显示的是完整的build.gradle,那么整个buildscript 块是无意义的。您将 Jackson 添加到构建脚本的类路径中,但您没有在任何地方使用它。在 buildscript 块中,您可以在构建脚本中添加所需的依赖项,例如一些 Gradle 插件等。

    【讨论】:

    • 是的,buildscript 块是我在搜索问题时发现的。正如我所提到的,我最近开始使用 Gradle,看起来我应该先在没有 Intellij 的情况下开始学习它。关于我的问题:使用application 插件,我设法运行了我的主类(使用.\gradlew run Start)。现在我需要将一些命令行参数传递给我的应用程序。你知道怎么做吗?不幸的是,谷歌并没有提供太多帮助。谢谢。
    • 您可以在构建脚本中对参数进行硬编码,或者您可以通过将项目属性提供给程序来对构建脚本中的参数进行半硬编码,然后您可以在 gradle 命令上设置这些属性与-P 一致,或者您可以使用installApp 而不是run,然后您在build/install/ 中拥有您现成的应用程序,就像它在分发zip 中一样,您可以从那里使用脚本运行它bin/,给他们任何参数,就像最终用户会做的那样。您应该阅读 Gradle 用户指南,它是学习 Gradle 的绝佳资源。
    【解决方案2】:

    假设您正在使用 java -jar .. 之类的东西从控制台运行您的类或 jar(您没有说明您是如何从控制台运行它的,或者您正在运行什么;如果不是,您应该在问题中澄清这一点),这似乎是正确的。 IDE 中的 Run 目标知道如何为您的应用设置类路径。

    可能有一个 IDE 目标来生成一个可运行的 jar,其中包含所有外部依赖项的引用。但是,如果您有一个裸 jar,则必须使用自定义类路径调用 JVM。或者,您可以汇总包含第三方库的可运行 jar。

    Gradle 会缓存依赖项 jar,因此您可以使用这些路径来构建类路径。

    【讨论】:

    • 我正在使用构建目录中的java Class 运行。 Gradle 将库存储在 jar 中的 .gradle 目录中。如何轻松地将它们添加到我的类路径中?
    • IDE 具有创建可分发和可运行 Jarfile 的手势。我记得 intellij idea 是如何在菜单中呈现这些手势的,但它们就在那里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    相关资源
    最近更新 更多