Gradleを介してJavaクラスを実行するときにシステムプロパティとパラメータを渡す際の問題


82

クイック統合テストの一環として、Gradle経由でコマンドラインJavaアプリを実行しようとしています。ビルドスクリプトをMavenから移植していexec-maven-pluginます。これは、を介して簡単に実行できます。私の2つの大きな要件は次のとおりです。

  • システムプロパティを実行可能なJavaコードに渡すことができる
  • コマンドライン引数を実行可能Javaコードに渡すことができる

ビルドスクリプトでこれらのプロパティを読み取ろうとしているのではなく、スクリプトがビルドして実行するJavaプログラムでこれらのプロパティを読み取ろうとしていることに注意してください。

私は2つの他のSOの記事を発見したそのアドレスのJavaプログラムのGradleを経由して実行:支持者が使用していることを答えと1apply plugin: "application"のビルドファイルとgradle runコマンドラインで、そして答えはそのアプローチを提唱だけでなく、使用して別のtask execute(type:JavaExec)ビルドファイルにとgradle executeでコマンドライン。私は両方のアプローチを試しましたが、成功しませんでした。

私には2つの問題があります:

(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 / missingとして読み取ります。

(2)コマンドライン引数を渡すことができません

これはおそらく最初の問題に関連しています。exec-maven-plugin例えば、コマンドライン引数は、それ自体がシステムプロパティを介して通過させました。それはGradleの場合ですか、それともコマンドライン引数を渡す別の方法がありますか?

これらの変数を取得するにはどうすればよいですか?また、それは良く使用することですapply plugin: 'application'task execute (type:JavaExec)

回答:


124

理解した。主な問題は、Gradleが新しいJavaプロセスをフォークするときに、環境変数の値を新しい環境に自動的に渡さないことです。systemPropertiesタスクまたはプラグインのプロパティを介して、これらの変数を明示的に渡す必要があります。

もう1つの問題は、コマンドライン引数を渡す方法を理解することでした。これらはargs、タスクまたはプラグインのプロパティを介して行われます。Mavenexec-maven-pluginと同様に、オブジェクトを受け入れるsplit()設定の前に必要なスペース区切りのリストとして、さらに別のシステムプロパティを介してコマンドラインで渡す必要があります。プロパティに名前を付けました。これは古いMavenの名前です。argsListexec.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()    
}

3
System.getProperties()(大文字のS)である必要があると思います。
orlanthi 2014

1
あなたはGradleの2.xxのを使用している場合は、次のように使用することができます-systemProperty "myvariable", "${myvariable}"
eadjei

1
ありがとうございました!私はCucumberテストを実行しようとしていて、環境変数をJVMに渡したいと思っていました。「systemPropertiesSystem.getProperties()」を実行{}ではなくテスト{}に配置しました
Svante

1
デフォルトの分割では、スペースを含む引数は許可されないことに注意してください。たとえば、-Dexec.args="--greeting 'hello there'"–は機能しません。別の区切り文字を設定する必要があります。
Ivan Balashov 2015

3
使用:args System.getProperty( "exec.args"、 "").split()は、引数が指定されていない場合にnullポインター例外を回避します。たとえば、「gradleタスク」でも、提案されたbuild.gradleで例外がスローされます
Mike Hanafey 2017年

12

無関係なGradle小道具を渡してアプリケーションのシステムプロパティを汚染したくない場合は、引数に名前を付けることをお勧めします。

tasks.withType(JavaExec) {
    System.properties.each { k,v->
        if (k.startsWith("prefix.")) {
            systemProperty k - "prefix.", v
        }
    }
}

java ... -Dprefix.my.prop=true 通過します my.prop


3

私はgradleを初めて使用するので、これが必要でした。gradle4.6で機能していることは、コマンドラインでは少し簡単に思えます。1つのarg文字列を解析する代わりに、argの配列を渡すことができます。また、すべてのプロパティを1行で渡す方法を見つけました。以下の組み合わせ:

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=

-2

パーティーに遅れるかもしれませんが、「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ピリオドで区切ることができないことに注意してください。それ以外の場合は、最初の期間より前の部分のみがキーとして使用されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.