Gradle任务 - 将参数传递给Java应用程序

157

我有一个Java应用程序,通过自定义Gradle任务运行,需要在调用时传递一些参数。这些参数是:

programName ( string | -f filename | -d key | -h)
Options:
    string         Message to be used.
    -d key         Use default messages, key must be s[hort], m[edium] or l[ong].
    -f filename    Use specified file as input.
    -h             Help dialog.

Gradle任务看起来像:

task run (type: JavaExec){
    description = "Secure algorythm testing"
    main = 'main.Test'
    classpath = sourceSets.main.runtimeClasspath
}

我已经尝试运行gradle run -h但是它没有起作用。


答案是否满足您的需求?如果是,您应该将其中一个标记为解决方案。 - Francisco J. Lopez-Pellicer
1
并不是真的...我和一个朋友发现了一种方法来做到这一点,但我们还没有弄清楚如何发布解决方案,两种提出的解决方案都尝试过了,我们理解了需要做什么,但似乎并没有真正起作用... - RecuencoJones
@6uitar6reat6od,最终你是如何解决的呢?另外,你使用的是哪个版本的Gradle? - xlm
8个回答

127

Gradle 4.9+

gradle run --args='arg1 arg2'

假设您的build.gradle已配置了Application插件,则它应该类似于下面这样:

plugins {
  // Implicitly applies Java plugin
  id: 'application'
}

application {
  // URI of your main class/application's entry point (required)
  mainClassName = 'org.gradle.sample.Main'
}

Gradle 4.9及其之前版本:

在您的build.gradle文件中包含以下内容:

run {
    if (project.hasProperty("appArgs")) {
        args Eval.me(appArgs)
    }
}

然后运行:gradle run -PappArgs="['arg1', 'args2']"


108

1
这个单引号是有意为之还是笔误呢?所有参数都应该作为由单引号分隔的字符串进行传递吗? - RecuencoJones
1
gradle run --args='foo --bar' - Jim Flood
4
“foo --bar”很令人困惑,为什么不直接使用“foo bar”呢? - Eric
4
这些是程序可能需要的任意命令行参数。展示gradle支持任何类型的参数很好,因为原始字符串将传递给构建的应用程序。 - Joffrey
如果您在使用gradle run --args='foo --bar'时遇到问题,请使用双引号 " "代替单引号 ' '。例如:gradle run --args="arg1 arg2"。 - keita063
显示剩余2条评论

39
如果您想一直使用相同的参数,则以下内容就是您所需的。
run {
    args = ["--myarg1", "--myarg2"]
}

3
对于像我一样的绝对初学者: 为了能够定义运行任务,您的build.gradle文件应包含以下两行: apply plugin:'application' mainClassName="<完整的类名,包括包路径>" 否则,在build.gradle中无法定义run方法。 - Sandeep
1
我正在使用id'application'插件,这就是我需要的答案(它有效)。 - Big Rich
1
我遇到了 "未解决的引用:args" 错误。Gradle 7.3。 - Henning

29

抱歉回复晚了。

我想我的答案与@xlm的类似:

task run (type: JavaExec, dependsOn: classes){
    if(project.hasProperty('myargs')){
        args(myargs.split(','))
    }
    description = "Secure algorythm testing"
    main = "main.Test"
    classpath = sourceSets.main.runtimeClasspath
}

然后像这样调用:

gradle run -Pmyargs=-d,s

6
当然,以上答案都可以胜任工作,但我仍然想使用类似于以下的东西。
gradle run path1 path2

好的,这是不可能完成的,但如果我们能做到呢:

gralde run --- path1 path2

如果您认为这更加优雅,那么可以这样做,诀窍是在gradle执行之前处理命令行并进行修改,这可以通过使用init脚本来实现。
以下是init脚本:
  1. 处理命令行并删除“---”及其后面的所有参数
  2. 将属性'appArgs'添加到gradle.ext中
因此,在您的run任务(或JavaExec、Exec)中,您可以:
if (project.gradle.hasProperty("appArgs")) {
                List<String> appArgs = project.gradle.appArgs;

                args appArgs

 }

初始化脚本是:

import org.gradle.api.invocation.Gradle

Gradle aGradle = gradle

StartParameter startParameter = aGradle.startParameter

List tasks = startParameter.getTaskRequests();

List<String> appArgs = new ArrayList<>()

tasks.forEach {
   List<String> args = it.getArgs();


   Iterator<String> argsI = args.iterator();

   while (argsI.hasNext()) {

      String arg = argsI.next();

      // remove '---' and all that follow
      if (arg == "---") {
         argsI.remove();

         while (argsI.hasNext()) {

            arg = argsI.next();

            // and add it to appArgs
            appArgs.add(arg);

            argsI.remove();

        }
    }
}

}


   aGradle.ext.appArgs = appArgs

限制:

  1. 我被迫使用“---”而不是“--”
  2. 您必须添加一些全局初始化脚本

如果您不喜欢全局初始化脚本,可以在命令行中指定它。

gradle -I init.gradle run --- f:/temp/x.xml

或者更好的是在你的shell中添加一个别名:

gradleapp run --- f:/temp/x.xml

2
这个方法很好用......如果我的任何参数都不以破折号开头的话。这使它对于常见的命令行解析器来说毫无用处: (https://commons.apache.org/proper/commons-cli/usage.html)。一旦发生这种情况,Gradle似乎会将该参数视为Gradle的参数(我认为argsI.remove()没有产生预期的效果)。有什么建议吗? - Krease

6

我也看到了。还在寻找中。所有这些方法似乎都想要编辑/调整当前属性并将其传递下去。运行应用程序或服务的命令行和Java属性类似于“上下文”或“配置”设置。最好有一个插件,可以像“运行参数”一样作为并排配置文件之类的东西来完成任务。 - will

4
您需要将它们作为参数通过项目属性传递给任务,例如: args
args = [project.property('h')]

已添加到您的任务定义中(请参见dsl文档)。

然后,您可以这样运行它:

gradle -Ph run

0
使用Kotlin DSL:
plugins {
    java
    application
}

application {
    mainClass = "io.fouad.AppLauncher"
    applicationDefaultJvmArgs = listOf("-Dsome.system.properties=123")
}

tasks.withType(JavaExec::class) {
    args = listOf("abc", "def")
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接