งาน Gradle - ส่งผ่านอาร์กิวเมนต์ไปยังแอปพลิเคชัน Java


127

ฉันมีแอปพลิเคชัน Java ที่ทำงานด้วยงาน gradle แบบกำหนดเองและแอปพลิเคชันต้องการอาร์กิวเมนต์เมื่อถูกเรียกใช้ เหล่านี้คือ:

programName ( string | -f filename | -d key | -h)
Options:
    string         Message to be used.
    -d key         Use default messages, key must be s[hort], m[edium] or l[ong].
    -f filename    Use specified file as input.
    -h             Help dialog.

งาน Gradle ดูเหมือนว่า:

task run (type: JavaExec){
    description = "Secure algorythm testing"
    main = 'main.Test'
    classpath = sourceSets.main.runtimeClasspath
}

ฉันได้ลองใช้งานgradle run -hแล้ว แต่ไม่ได้ผล


คำตอบตรงกับความต้องการของคุณหรือไม่? ถ้าเป็นเช่นนั้นคุณควรทำเครื่องหมายว่าเป็นโซลูชัน
Francisco J.Lopez-Pellicer

1
ไม่จริง ... เพื่อนคนหนึ่งและฉันค้นพบวิธีที่จะทำ แต่เรายังไม่มีความชัดเจนในการเผยแพร่วิธีแก้ปัญหาทั้งสองวิธีที่นำเสนอได้พยายามแล้วเราเข้าใจว่าจะต้องทำอะไร แต่ก็ไม่ได้ ' ดูเหมือนจะได้ผลจริงๆ ...
RecuencoJones

@ 6uitar6reat6od สุดท้ายแล้วคุณแก้ยังไง gradle รุ่นอะไร
xlm

คำตอบ:


80

ตั้งแต่ Gradle 4.9 อาร์กิวเมนต์บรรทัดคำสั่งสามารถส่งผ่านด้วย --args ตัวอย่างเช่นหากคุณต้องการเปิดแอปพลิเคชันด้วยอาร์กิวเมนต์บรรทัดคำสั่งfoo --barคุณสามารถใช้

gradle run --args = 'foo --bar'

ดูปลั๊กอินแอปพลิเคชัน Gradle ด้วย

วิธีอัปเกรด Gradle wrapper


1
'คาดว่าหรือพิมพ์ผิด? ควรส่งอาร์กิวเมนต์ทั้งหมดเป็นสตริงที่คั่นด้วยเครื่องหมายคำพูดเดี่ยวหรือไม่
RecuencoJones

@RecuencoJones คงที่ต่อdocs.gradle.org/current/userguide/…
Drew Stephens

1
gradle run --args = 'foo --bar'
Jim Flood

3
'foo --bar'สับสนทำไมไม่ใช้แค่'foo bar'.
Eric Wang

4
@EricWang นี่คืออาร์กิวเมนต์บรรทัดคำสั่งที่โปรแกรมอาจต้องการ เป็นเรื่องดีที่แสดงให้เห็นว่า gradle รองรับอาร์กิวเมนต์ทุกประเภทเนื่องจากสตริงดิบจะถูกส่งไปยังแอปพลิเคชันที่สร้างขึ้น
Joffrey

100

Gradle 4.9+

gradle run --args='arg1 arg2'

นี้จะถือว่าคุณbuild.gradleมีการกำหนดค่าด้วยปลั๊กอินแอพลิเคชัน คุณbuild.gradleควรมีลักษณะคล้ายกับสิ่งนี้:

plugins {
  // Implicitly applies Java plugin
  id: 'application'
}

application {
  // URI of your main class/application's entry point (required)
  mainClassName = 'org.gradle.sample.Main'
}

Pre-Gradle 4.9.1

รวมสิ่งต่อไปนี้ไว้ในbuild.gradle:

run {
    if (project.hasProperty("appArgs")) {
        args Eval.me(appArgs)
    }
}

จากนั้นเพื่อเรียกใช้: gradle run -PappArgs="['arg1', 'args2']"


7
คำตอบนี้ไม่เพียง แต่มีประโยชน์เท่านั้น แต่ยังง่ายที่สุด
Jossie Calderon

อัปเดตสำหรับการอัปเดตของคุณ: gradle run --args 'arg1 arg2'ไม่ได้ผลสำหรับฉัน ฉันต้องทำ:gradle run --args='arg1 arg2'
cmyers

@cmyers ขอบคุณที่จับได้! ฉันได้อัปเดตการอัปเดตของฉันแล้ว
xlm

28

ขออภัยที่ตอบช้า

ฉันคิดคำตอบเหมือนกันสำหรับ @xlm:

task run (type: JavaExec, dependsOn: classes){
    if(project.hasProperty('myargs')){
        args(myargs.split(','))
    }
    description = "Secure algorythm testing"
    main = "main.Test"
    classpath = sourceSets.main.runtimeClasspath
}

และเรียกร้องเช่น:

gradle run -Pmyargs=-d,s

28

หากคุณต้องการใช้อาร์กิวเมนต์ชุดเดิมตลอดเวลาสิ่งต่อไปนี้คือสิ่งที่คุณต้องการ

run {
    args = ["--myarg1", "--myarg2"]
}

2
โอเคสำหรับผู้เริ่มต้นอย่างฉัน: เพื่อให้สามารถกำหนด run task build.gradle ของคุณควรมีสองบรรทัดต่อไปนี้: ใช้ plugin: 'application' mainClassName = "<full classname including the package path>" มิฉะนั้นคุณจะไม่สามารถกำหนดได้ วิธีการรันใน buuild.gradle
mk ..

1
ฉันใช้id 'application'ปลั๊กอินและนี่คือคำตอบที่ฉันต้องการ (ใช้งานได้)
Big Rich

6

คุณสามารถหาทางออกในปัญหาที่ผ่านคุณสมบัติของระบบและพารามิเตอร์เมื่อทำงานระดับ Java ผ่าน Gradle ทั้งสองอย่างเกี่ยวข้องกับการใช้argsทรัพย์สิน

นอกจากนี้คุณควรอ่านความแตกต่างระหว่างการส่งด้วย-Dหรือกับ-Pที่อธิบายไว้ในเอกสาร Gradle


เห็นแบบนี้ด้วย. ยังคงตามหา. วิธีการทั้งหมดนี้ดูเหมือนจะต้องการแก้ไข / นวดคุณสมบัติปัจจุบันและส่งต่อไป คุณสมบัติของบรรทัดคำสั่งและ Java สำหรับการเรียกใช้แอปพลิเคชันหรือบริการนั้นคล้ายกับการตั้งค่า "บริบท" หรือ "การกำหนดค่า" มันจะดีกว่าถ้ามีปลั๊กอินที่ทำสิ่งต่างๆเช่น "เรียกใช้พารามิเตอร์" เป็นโปรไฟล์แบบเคียงข้างกันหรือบางอย่าง
จะ

5

แน่นอนคำตอบข้างต้นทำงานได้ดี แต่ฉันก็ยังอยากจะใช้สิ่งที่ชอบ

gradle run path1 path2

สิ่งนี้ไม่สามารถทำได้ แต่ถ้าเราทำได้:

gralde run --- path1 path2

หากคุณคิดว่ามันสวยกว่าคุณก็ทำได้เคล็ดลับคือการประมวลผลบรรทัดคำสั่งและแก้ไขก่อนที่จะทำการ gradle ซึ่งสามารถทำได้โดยใช้สคริปต์ init

สคริปต์ init ด้านล่าง:

  1. ประมวลผลบรรทัดคำสั่งและลบ --- และอาร์กิวเมนต์อื่น ๆ ทั้งหมดตาม '---'
  2. เพิ่มคุณสมบัติ 'appArgs' ไปที่ gradle.ext

ดังนั้นในงานรันของคุณ (หรือ JavaExec, Exec) คุณสามารถ:

if (project.gradle.hasProperty("appArgs")) {
                List<String> appArgs = project.gradle.appArgs;

                args appArgs

 }

สคริปต์ init คือ:

import org.gradle.api.invocation.Gradle

Gradle aGradle = gradle

StartParameter startParameter = aGradle.startParameter

List tasks = startParameter.getTaskRequests();

List<String> appArgs = new ArrayList<>()

tasks.forEach {
   List<String> args = it.getArgs();


   Iterator<String> argsI = args.iterator();

   while (argsI.hasNext()) {

      String arg = argsI.next();

      // remove '---' and all that follow
      if (arg == "---") {
         argsI.remove();

         while (argsI.hasNext()) {

            arg = argsI.next();

            // and add it to appArgs
            appArgs.add(arg);

            argsI.remove();

        }
    }
}

}


   aGradle.ext.appArgs = appArgs

ข้อ จำกัด :

  1. ฉันถูกบังคับให้ใช้ '---' ไม่ใช่ '-'
  2. คุณต้องเพิ่ม global init script

หากคุณไม่ชอบ global init script คุณสามารถระบุได้ในบรรทัดคำสั่ง

gradle -I init.gradle run --- f:/temp/x.xml

หรือดีกว่าเพิ่มนามแฝงในเชลล์ของคุณ:

gradleapp run --- f:/temp/x.xml

2
มันใช้งานได้ดี ... ถ้าไม่มีอาร์กิวเมนต์ของฉันเริ่มต้นด้วยเครื่องหมายขีดกลาง สิ่งนี้ทำให้ไม่มีประโยชน์สำหรับตัวแยกวิเคราะห์บรรทัดคำสั่งทั่วไป:( ทันทีที่เกิดขึ้น gradle ดูเหมือนจะถือว่าอาร์กิวเมนต์นั้นเป็นอาร์กิวเมนต์เพื่อไล่ระดับ (ฉันไม่คิดว่าargsI.remove()จะมีเอฟเฟกต์ที่ต้องการ) คำแนะนำ?
Krease

4

คุณต้องส่งผ่านมันargsไปยังงานโดยใช้คุณสมบัติของโปรเจ็กต์เช่น:

args = [project.property('h')]

เพิ่มเข้าไปในข้อกำหนดงานของคุณ (ดูเอกสาร dsl )

จากนั้นคุณสามารถเรียกใช้เป็น:

gradle -Ph run
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.