我有一个 build.gradle
创建 java WAR
的文件文件。此文件用于 Docker 多阶段构建的一个阶段,以生成我在生产、暂存等中使用的 Docker 镜像(配置文件/ secret 在镜像之外)。
但是在开发中,虽然大部分时间我都是用普通的build来生成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
The JavaExec task has a task action which executes the Java program. By using <<, you’re adding the configuration of the main, classpath, and args as a task action as well. When the task action provided by the JavaExec runs, the second task action to configure these values has not run yet. You likely want to configure these values in the configuration phase, not in a task action by removing the <<.
如果我删除
doLast
,错误不会发生方法,但最初的问题仍未解决。所以我想知道的是是否有办法(以及如何)制作
execFile
里面的东西。任务仅在显式调用此任务时运行。 (以便在运行其他任务时不会引起任何副作用)
最佳答案
您可以使用包装任务解决这个问题,方法是在运行时在其 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()
}
}
关于gradle - 仅在专门调用时运行 gradle 任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54347157/