ग्रैडल के माध्यम से जावा वर्ग को चलाते समय सिस्टम गुण और मापदंडों को पारित करने में समस्याएं


82

मैं एक त्वरित एकीकरण परीक्षण के भाग के रूप में ग्रैडल के माध्यम से एक कमांड-लाइन जावा ऐप चलाने की कोशिश कर रहा हूं। मैं मावेन से अपनी बिल्ड स्क्रिप्ट को पोर्ट कर रहा हूं, जहां यह आसानी से हो गया था exec-maven-plugin। मेरी दो बड़ी आवश्यकताएं हैं:

  • निष्पादन योग्य जावा कोड में सिस्टम गुण पास करने में सक्षम होने के नाते
  • कमांड-लाइन को पास करने में सक्षम होने के कारण निष्पादन योग्य जावा कोड

कृपया ध्यान दें कि मैं इन गुणों को बिल्ड स्क्रिप्ट में पढ़ने की कोशिश नहीं कर रहा हूं, मैं उन्हें जावा प्रोग्राम में पढ़ने की कोशिश कर रहा हूं जो स्क्रिप्ट बनाता है और निष्पादित करता है।

मुझे दो अन्य एसओ पोस्ट मिले हैं जो ग्रैड के माध्यम से जावा प्रोग्राम निष्पादन को संबोधित करते हैं: एक उत्तर के साथ जो apply plugin: "application"बिल्ड फ़ाइल में और gradle runकमांड लाइन पर उपयोग करने की वकालत करता हैtask execute(type:JavaExec)gradle execute , और दूसरा उत्तर उस दृष्टिकोण की वकालत करने के साथ-साथ बिल्ड फ़ाइल में और उपयोग करने पर कमांड लाइन । मैंने दोनों तरीकों की कोशिश की है और सफल नहीं हुआ हूं।

मुझे दो समस्याएं हैं:

(1) मुझे सिस्टम के गुणों को पढ़ने के लिए जावा निष्पादन योग्य नहीं मिल सकता है

चाहे मैं यह करूँ:

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सिस्टम प्रॉपर्टी को अशक्त / लापता के रूप में पढ़ता है।

(2) मैं कमांड लाइन तर्क पारित नहीं कर सकता

यह संभवतः पहली समस्या से संबंधित है। में exec-maven-plugin, उदाहरण के लिए, कमांड लाइन आर्ग खुद को एक प्रणाली के माध्यम से संपत्ति में पारित किया गया। क्या ग्रैडल के साथ मामला है, या कमांड लाइन तर्कों को पारित करने का एक और तरीका है?

मैं इन चर को कैसे प्राप्त करूं? इसके अलावा, क्या इसका उपयोग करना बेहतर है apply plugin: 'application'या task execute (type:JavaExec)?

जवाबों:


124

पता लगा लिया। मुख्य मुद्दा यह है कि जब ग्रेडल एक नई जावा प्रक्रिया की तलाश करता है, तो यह नए परिवेश के साथ पर्यावरण चर मूल्यों को स्वचालित रूप से पारित नहीं करता है। किसी को systemPropertiesकार्य या प्लगइन की संपत्ति के माध्यम से इन चर को स्पष्ट रूप से पास करना होगा ।

दूसरा मुद्दा यह समझ रहा था कि कमांड-लाइन आर्गन्स कैसे पारित किया जाए; ये argsकार्य या प्लगइन पर संपत्ति के माध्यम से होते हैं। मावेन के साथ exec-maven-plugin, उन्हें कमांड लाइन पर अभी तक एक और सिस्टम प्रॉपर्टी के माध्यम से पारित किया जाना चाहिए, एक अंतरिक्ष-सीमांकित सूची के रूप में जिसे तब split()सेटिंग से पहले होना चाहिए 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()    
}

3
मुझे लगता है कि System.getProperties () (कैपिटल S) होना चाहिए।
orlanthi

1
यदि आप 2.xx का प्रयोग कर रहे हैं, तो आप निम्न का भी उपयोग कर सकते हैं: -systemProperty "myvariable", "${myvariable}"
eadjei

1
धन्यवाद! मैंने कहा कि ककड़ी परीक्षण चलाने की कोशिश कर रहा था और जेवीएम के लिए पर्यावरण चर को पारित करना चाहता था। मैंने अभी टेस्ट {} में रन {} के बजाय "systemProperties System.getProperties ()" को रखा
Svante

1
कृपया ध्यान दें कि डिफ़ॉल्ट विभाजन रिक्त स्थान के साथ तर्क की अनुमति नहीं देता है, जैसे -Dexec.args="--greeting 'hello there'"- काम नहीं करेगा, एक और सीमांकक सेट करने की आवश्यकता है।
इवान

3
का प्रयोग करें: args System.getProperty ("exec.args", "") .Split () अशक्त सूचक अपवाद से बचने के लिए यदि कोई args की आपूर्ति नहीं की जाती है। उदाहरण के लिए, यहां तक कि 'Gradle कार्य' का सुझाव दिया build.gradle साथ एक अपवाद फेंक देते हैं
माइक Hanafey

12

जो लोग असंबंधित ग्रेडल प्रॉप्स पास करके आपके आवेदन के सिस्टम गुणों को प्रदूषित नहीं करना चाहते हैं, मैं आपके तर्कों को नाम देने की सलाह देता हूं।

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 4.6 कमांड लाइन के लिए थोड़ा आसान लगता है। 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

हो सकता है कि मुझे पार्टी में देर हो गई हो, लेकिन क्या किसी ने "कांड को अंजाम देने से पहले प्रोप सेट किया है"? मैंने परीक्षण किया है और यह भी स्पष्ट रूप से काम करता है।

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समय-अलग नहीं किया जा सकता है; या केवल पहली अवधि से पहले का हिस्सा ही कुंजी के रूप में लिया जाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.