仅在明确调用时运行gradle任务

时间:2019-01-24 12:54:11

标签: gradle

我有一个build.gradle文件,它创建了一个Java WAR文件。该文件用于Docker多阶段构建的一个阶段,以生成我在生产,登台等过程中使用的Docker映像(配置文件/密钥不在映像之内)。

但是在开发中,尽管大多数时候我都是使用普通版本生成WAR文件(或爆炸的WAR),并且效果很好,但有时我只想执行一个Java文件 >在我的项目中有一个主班。

我实现了在文件中添加以下内容:

task execFile(type: JavaExec) {
    main = mainClass

    classpath = sourceSets.main.runtimeClasspath

    if (System.getProperty('debug', 'false') == 'true') {
        jvmArgs "-Xdebug", "-agentlib:jdwp=transport=dt_socket,address=8788,server=y,suspend=y"
    }

    systemProperties System.getProperties()
}

然后,我可以使用以下命令执行传递系统属性的文件

gradle execFile -PmainClass=com.mysite.MyClass -Dsomeprop=somevalue

如果要调试,请运行:

gradle execFile -PmainClass=com.mysite.MyClass -Dsomeprop=somevalue -Ddebug=true

通过这种方式,我可以执行(和调试)单个文件,这在开发过程中的某些情况下非常有用,但问题是即使我未明确运行execFile,该代码也会被执行。

这会在生成和生成WAR文件时导致错误,所以我正在做的事情是注释这些行,运行单个文件时取消注释,并在运行后再次注释(记住)这些文件,然后再推送git repo(否则docker构建过程最终会出错)。

这很糟糕,我知道。

根据我的理解,该代码在配置阶段期间运行,并且为了使该代码在任务的执行中运行,我可以添加代码doLast方法内(或使用简写<<):

Why does gradle run every task in gradle.build

但是在这种情况下,我会收到错误No main class specified,这可能是由于本讨论中所述的相同原因所致:

https://discuss.gradle.org/t/javexec-error-no-main-class-specified/12731

  

JavaExec任务具有执行Java程序的任务动作。   通过使用<<,您将添加主类路径的配置,   和args作为任务动作。当任务动作由   JavaExec运行时,第二个任务操作就是配置这些值   尚未运行。您可能需要在   配置阶段,而不是通过删除<<。

来执行任务操作

如果我删除了doLast方法,则不会发生该错误,但是最初的问题仍然没有解决。

所以我想知道的是,是否有一种方法(以及如何)使execFile任务中的内容仅在显式调用此任务时才运行。

(以便在运行其他任务时不会引起任何副作用)

1 个答案:

答案 0 :(得分:3)

您可以通过在运行时在doLast { }闭包内创建所需的JavaExec来解决包装问题。

对于Groovy DSL:

task myTask {
    group = 'MyGroup'
    description = 'Runs Hello.java'
    dependsOn 'build'

    doLast {
        tasks.create('myTaskExec', JavaExec) {
            main = 'com.example.Hello'
            args = ['foo', 'bar']
            classpath = sourceSets.main.runtimeClasspath
        }.exec()
    }
}

对于Kotlin DSL:

tasks.register("myTask") {
    group = "MyGroup"
    description = "Runs Hello.java"
    dependsOn(mutableListOf("build"))

    doLast {
        tasks.create<JavaExec>("myTaskExec") {
            main = "com.example.Hello" 
            args = mutableListOf("foo", "bar")
            classpath = sourceSets.main.get().runtimeClasspath
        }.exec()
    }
}

请注意,在两个示例中,应该在包装任务中声明另一个任务的依赖关系,而不是在JavaExec中声明。

进行此更改后,您的任务应仅在调用时运行:

task execFile {
    dependsOn 'build'

    doLast {
        tasks.create('execFileJavaExec', JavaExec) {
            main = mainClass
            classpath = sourceSets.main.runtimeClasspath

            if (System.getProperty('debug', 'false') == 'true') {
                jvmArgs "-Xdebug", "-agentlib:jdwp=transport=dt_socket,address=8788,server=y,suspend=y"
            }

            systemProperties System.getProperties()
        }.exec()
    }
}