用于构建和运行作品的任务,但不使用生成的运行脚本执行

时间:2019-03-10 13:00:17

标签: java linux gradle build.gradle gradlew

我正在从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'
}

1 个答案:

答案 0 :(得分:0)

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.withWriter {
            it.write("""java -classpath $classpath.asPath ${details.mainClassName}""")
        }
    }
}

您可以根据需要扩展它。