빠른 통합 테스트의 일부로 Gradle을 통해 명령 줄 Java 앱을 실행하려고합니다. Maven에서 빌드 스크립트를 이식하고 있는데 exec-maven-plugin
. 내 두 가지 큰 요구 사항은 다음과 같습니다.
- 시스템 속성을 실행 가능한 Java 코드로 전달할 수 있음
- 실행 가능한 Java 코드에 명령 줄 인수를 전달할 수 있음
빌드 스크립트에서 이러한 속성을 읽으려는 것이 아니라 스크립트가 빌드하고 실행하는 Java 프로그램에서 읽으려고한다는 점에 유의하십시오.
나는 다른 두 SO의 게시물을 발견 한 그 주소 자바 프로그램 Gradle을 통해 실행 : 옹호 사용한다는 대답 한 apply plugin: "application"
빌드 파일과 gradle run
명령 줄에서 , 그리고 대답은 그 접근 방식을 옹호뿐만 아니라 사용하여 다른 task execute(type:JavaExec)
빌드 파일과 gradle execute
상기 명령 줄 . 나는 두 가지 접근법을 모두 시도했지만 성공하지 못했습니다.
두 가지 문제가 있습니다.
(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
시스템 속성을 null / 누락으로 읽습니다 .
(2) 명령 줄 인수를 전달할 수 없습니다.
이것은 아마도 첫 번째 문제와 관련이 있습니다. 에서은 exec-maven-plugin
, 예를 들어, 명령 줄 인수 자체가 시스템 속성을 통해 전달했다. Gradle의 경우입니까, 아니면 명령 줄 인수를 전달하는 다른 방법이 있습니까?
이 변수를 어떻게 얻습니까? 또한 apply plugin: 'application'
또는 사용하는 것이 더 낫 task execute (type:JavaExec)
습니까?
답변
그것을 알아 냈습니다. 주요 문제는 Gradle이 새 Java 프로세스를 포크 할 때 새 환경에 환경 변수 값을 자동으로 전달하지 않는다는 것입니다. systemProperties
작업 또는 플러그인 의 속성을 통해 이러한 변수를 명시 적으로 전달해야합니다 .
다른 문제는 명령 줄 인수를 전달하는 방법을 이해하는 것이 었습니다. 이는 args
작업 또는 플러그인 의 속성을 통해 이루어 집니다. Maven과 마찬가지로 exec-maven-plugin
, 그것들은 또 다른 시스템 속성을 통해 명령 줄에 전달되어야합니다. 공백으로 구분 된 목록 은 객체 를 받아들이는 split()
setting 전에 있어야 합니다. 이전 Maven 이름 인 속성의 이름을 지정했습니다.args
List
exec.args
javaExec
및 응용 프로그램 플러그인 접근 방식이 모두 유효한 것 같습니다 . 다른 기능 중 일부를 사용하려는 경우 애플리케이션 플러그인 접근 방식을 선호 할 수 있습니다 (배포판을 자동으로 구성하는 등).
해결책은 다음과 같습니다.
JavaExec 접근 방식
명령 줄 :
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 소품을 전달하여 애플리케이션의 시스템 속성을 오염시키지 않으려는 사람들을 위해 인수 이름 간격을 지정하는 것이 좋습니다.
tasks.withType(JavaExec) {
System.properties.each { k,v->
if (k.startsWith("prefix.")) {
systemProperty k - "prefix.", v
}
}
}
java ... -Dprefix.my.prop=true
통과 할 것이다 my.prop
답변
나는 gradle을 처음 사용했기 때문에 이것이 필요했고 gradle 4.6에서 나를 위해 작동하는 것이 명령 줄에서 조금 더 쉬워 보입니다. 1 개의 arg 문자열을 구문 분석하는 대신 args 배열을 전달할 수 있으며 한 줄로 모든 속성을 전달할 수있는 방법을 찾았습니다. 아래 결합 :
apply plugin: 'java'
apply plugin: 'org.springframework.boot' <- for my project
task runApp(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'testit.TomcatApp'
// arguments to pass to the application
// args 'myarg1 -rest' <- came in as 1 string
args = ["--myarg1 with spaces even", "--myarg2"]
// and to pass in all -D system property args:
systemProperties = System.properties
}
gradle run -Dwhatever=xxx -Dmyarg2=hey
// Java reading them:
public static void main(String[] args) {
for ( int i = 0; i < args.length; i++ )
{
logger.info( "** args [" + i + "] =" + args[i] + "=" );
}
logger.info( "** -Dwhatever =" + System.getProperty("whatever") + "=" );
logger.info( "** -Dmyarg2 =" + System.getProperty("myarg2") + "=" );
[main] INFO testit.TomcatApp - ** args [0] =--myarg1 with spaces even=
[main] INFO testit.TomcatApp - ** args [1] =--myarg2=
[main] INFO testit.TomcatApp - ** -Dwhatever =xxx=
[main] INFO testit.TomcatApp - ** -Dmyarg2 =hey=
답변
내가 파티에 늦었을지도 모르지만, “Gradle을 실행하기 전에 소품 설정”을 시도한 사람이 있습니까? 나는 테스트했고 이것도 분명히 작동합니다.
myVar=myVal gradle test
예를 들어 다음과 같이 활성 프로필을 설정할 수 있습니다.
SPRING_PROFILES_ACTIVE=dev gradle test
이것도 분명히 작동합니다.
set myVar=myVal && gradle test # for windows
export myVar=myVal && gradle test # for linux and mac
그주의하십시오 myVar
기간으로 구분 될 수 없다; 그렇지 않으면 첫 번째 피리어드 이전의 부분 만 키로 간주됩니다.