【问题标题】:Tasks for build and run works but executing with the generated run script doesn't构建和运行任务有效,但使用生成的运行脚本执行不
【发布时间】:2019-07-31 22:40:10
【问题描述】:

我正在做来自https://spring.io/guides/gs/gradle/ 的简单 HelloWorld 示例。

我必须对build.gradle 进行一些更改(我在 Ubuntu 18 上使用 Gradle 5.2.1)。我使用了 gradlew 包装器。我设法让“构建”和“运行”等任务正常工作。似乎一切都是正确生成的。但是使用生成的build/scripts/<appscript> 在没有 gradle 的情况下运行应用程序不起作用。使用

运行 jar
java -jar build/libs/hello-1.0.jar

有效。但是

./build/scripts/sayhello

不起作用并产生错误:

erno@moongate:~/Projects/java/sayhello$ ./build/scripts/sayhello 
Error: Could not find or load main class hello.HelloWorld
Caused by: java.lang.ClassNotFoundException: hello.HelloWorld

项目文件结构如建议:

sayhello/
    build.gradle
    gradlew
    src/
        main/
        java/
        hello/
            Greeter.java
            HelloWorld.java

我不得不将清单和 mainclass 属性添加到构建配置文件中,因为 gradle init --type java-application 似乎没有这样做。这意味着即使尝试运行 gradle 生成的基础项目也不起作用。

我的build.gradle是这样的:

plugins {
    id 'java'
    id 'application'
}

mainClassName = 'hello.HelloWorld'

repositories {
    mavenCentral()
    jcenter()
}

dependencies {
    compile "joda-time:joda-time:2.10"
    testCompile "junit:junit:4.12"
}

jar {
    manifest {
        attributes(
            'Main-Class': 'hello.HelloWorld'
        )
    }
    baseName = 'hello'
    version = '1.0'
}

【问题讨论】:

  • 我添加了一个 settings.gradle 文件来覆盖默认行为,现在它为编译工件创建了 hello* 而不是 sayhello*。现在运行生成的 jar 不再起作用。我不确定这是我最近的修改还是其他原因造成的。
  • 这个项目可以在git中找到:github.com/codesmith-fi/hello
  • 附注:Java 8 有一个 time API 可以替代 joda time。 Java 8 已弃用 Aka joda 时间

标签: java linux gradle build.gradle gradlew


【解决方案1】:

startScripts 任务的问题在于它生成了一个非常基本的脚本。它不能确保依赖的 jar 文件在正确的位置——它希望这由你来完成。此外,它还假设您将从它称为 $APP_HOME 的目录运行脚本,并且该文件夹需要包含一个 lib 文件夹,其中包含您的应用所需的所有 jar。

我非常老套的解决方案是生成一个更基本的 unix 脚本,而不是依赖默认脚本。

startScripts {
    dependsOn jar
    doFirst {
        unixStartScriptGenerator = configure(new CustomUnixStartScript()) {
            classpath = configurations.runtimeClasspath + jar.outputs.files
        }
    }
}

class CustomUnixStartScript implements ScriptGenerator {
    @InputFiles
    FileCollection classpath

    @Override
    void generateScript (JavaAppStartScriptGenerationDetails details, Writer destination) {
        destination << """java -classpath $classpath.asPath ${details.mainClassName}"""
    }
}

您可以根据需要扩展它。

【讨论】:

    猜你喜欢
    • 2015-09-26
    • 1970-01-01
    • 2022-09-28
    • 2021-07-01
    • 2015-12-06
    • 1970-01-01
    • 2017-12-05
    • 1970-01-01
    • 2013-12-13
    相关资源
    最近更新 更多