Gradle을 통해 Java 클래스를 실행할 때 시스템 속성 및 매개 변수 전달 문제
빠른 통합 테스트의 일부로 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()
}
For those who might not want to pollute your application's system properties by passing unrelated Gradle props, I recommend namespacing your arguments.
tasks.withType(JavaExec) {
System.properties.each { k,v->
if (k.startsWith("prefix.")) {
systemProperty k - "prefix.", v
}
}
}
java ... -Dprefix.my.prop=true
will pass my.prop
I'm new to gradle so I needed this and what is working for me with gradle 4.6 seems a little easier for the command line. Instead of parsing 1 arg string you can pass an array of args, and I found a way to pass in all property with one line as well. Combined below:
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=
Maybe I am late for the party, but has anyone tried with "set the prop before executing gradle"? I have tested and this works too, apparently.
myVar=myVal gradle test
For example, you can set the active profile like:
SPRING_PROFILES_ACTIVE=dev gradle test
These also work, apparently:(tested)
set myVar=myVal && gradle test # for windows
export myVar=myVal && gradle test # for linux and mac
Be wary that myVar
cannot be period-separated; or else only the part before the first period will be taken as key.
'IT TIP' 카테고리의 다른 글
Laravel 컨트롤러 하위 폴더 라우팅 (0) | 2020.10.17 |
---|---|
Docker-Compose는 Docker 데몬에 연결할 수 없습니다. (0) | 2020.10.17 |
OpenGraph 또는 Schema.org? (0) | 2020.10.16 |
OWIN 보안-OAuth2 새로 고침 토큰 구현 방법 (0) | 2020.10.16 |
컴포넌트의 Reactjs 비동기 렌더링 (0) | 2020.10.16 |