通过 Gradle 运行 Java 类时传递系统属性和参数的问题 [英] Problems passing system properties and parameters when running Java class via Gradle
问题描述
作为快速集成测试的一部分,我正在尝试通过 Gradle 运行命令行 Java 应用程序.我正在从 Maven 移植我的构建脚本,这很容易通过 exec-maven-plugin
完成.我的两大要求是:
I am trying to run a command-line Java app via Gradle as part of a quick integration test. I am porting my build scripts from Maven, where this was easily done via exec-maven-plugin
. My two big requirements are:
- 能够将系统属性传递给可执行的 Java 代码
- 能够将命令行参数传递给可执行的 Java 代码
请注意,我不是要在构建脚本中读取这些属性,而是要在脚本构建和执行的 Java 程序中读取它们.
Please note that I am not trying to read these properties in the build script, I'm trying to read them in the Java program that the script builds and executes.
我发现了另外两篇通过 Gradle 解决 Java 程序执行问题的 SO 帖子:一个答案是提倡在构建文件中使用 apply plugin: "application"
并在命令行中使用 gradle run
和 另一个也支持这种方法的答案如在构建文件中使用 task execute(type:JavaExec)
和在命令行中使用 gradle execute
.这两种方法我都试过了,都没有成功.
I have found two other SO posts that address Java program execution via Gradle: one with an answer that advocates using apply plugin: "application"
in the build file and gradle run
at the command line, and another with answers advocating that approach as well as using task execute(type:JavaExec)
in the build file and gradle execute
at the command line. I have tried both approaches and have not succeeded.
我有两个问题:
(1) 我无法让 Java 可执行文件读取系统属性
我是否这样做:
build.gradle:
apply plugin: 'application'
mainClassName = "com.mycompany.MyMain"
命令行:
gradle run -Dmyproperty=myvalue
或者这个:
build.gradle:
task execute (type:JavaExec) {
main = "com.mycompany.MyMain"
classpath = sourceSets.main.runtimeClasspath
}
命令行:
gradle execute -Dmyproperty=myvalue
无论哪种情况,myproperty
都无法通过.从 MyMain.main (...)
开始运行的代码读取 myproperty
系统属性为空/缺失.
In either case, myproperty
does not make it through. The code that begins running from MyMain.main (...)
reads the myproperty
system property as null/missing.
(2) 我无法传递命令行参数
这大概和第一个问题有关.例如,在 exec-maven-plugin
中,命令行参数本身是通过系统属性传入的.Gradle 是这种情况,还是有另一种传递命令行参数的方法?
This is probably related to the first problem. In exec-maven-plugin
, for example, command line args were themselves passed in via a system property. Is that the case with Gradle, or is there another way to pass command line arguments?
如何获取这些变量?另外,使用 apply plugin: 'application'
还是 task execute (type:JavaExec)
更好?
How do I get these variables through? Also, is it better to use apply plugin: 'application'
or task execute (type:JavaExec)
?
推荐答案
想通了.主要问题是,当 Gradle 派生一个新的 Java 进程时,它不会自动将环境变量值传递给新环境.必须通过任务或插件的 systemProperties
属性显式传递这些变量.
Figured it out. The main issue is that when Gradle forks a new Java process, it does not automatically pass the environment variable values along to the new environment. One has to explicitly pass these variables via the systemProperties
property of the task or plugin.
另一个问题是理解如何传递命令行参数;这些是通过任务或插件的 args
属性实现的.与 Maven exec-maven-plugin
一样,它们应该通过另一个系统属性在命令行上传递,作为一个空格分隔的列表,然后需要 split()
在设置 args
之前,它接受 List
对象.我将属性命名为 exec.args
,这是旧的 Maven 名称.
The other issue was understanding how to pass command-line args; these are via the args
property on the task or plugin. As with the Maven exec-maven-plugin
, they should be passed in on the command line via yet another system property, as a space-delimited list that then needs to be split()
before setting args
, which accepts List
objects. I've named the property exec.args
, which is the old Maven name.
看来 javaExec
和应用程序插件方法都是有效的.如果您想使用应用程序插件的一些其他功能(自动组合发行版等),则可能更喜欢应用程序插件方法.
It seems both the javaExec
and application plugin approach are valid. One might favor the application plugin approach if one wants to use some of its other features (automatically putting together a distribution, etc.)
以下是解决方案:
命令行:
gradle execute -Dmyvariable=myvalue -Dexec.args="arg1 arg2 arg3"
build.gradle:
task execute (type:JavaExec) {
main = "com.myCompany.MyMain"
classpath = sourceSets.main.runtimeClasspath
/* Can pass all the properties: */
systemProperties System.getProperties()
/* Or just each by name: */
systemProperty "myvariable", System.getProperty("myvariable")
/* Need to split the space-delimited value in the exec.args */
args System.getProperty("exec.args", "").split()
}
应用插件方法
命令行:
gradle run -Dmyvariable=myvalue -Dexec.args="arg1 arg2 arg3"
build.gradle:
apply plugin: 'application'
mainClassName = "com.mycompany.MyMain"
run {
/* Can pass all the properties: */
systemProperties System.getProperties()
/* Or just each by name: */
systemProperty "myvariable", System.getProperty("myvariable")
/* Need to split the space-delimited value in the exec.args */
args System.getProperty("exec.args", "").split()
}
这篇关于通过 Gradle 运行 Java 类时传递系统属性和参数的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!