Gradle เพื่อรันคลาส Java (โดยไม่ต้องแก้ไข build.gradle)


119

มีปลั๊กอิน Eclipse อย่างง่ายในการเรียกใช้ Gradle ซึ่งใช้เพียงแค่ใช้บรรทัดคำสั่งเพื่อเรียกใช้ gradle

gradle analog สำหรับ maven คอมไพล์และรันคืออะไร mvn compile exec:java -Dexec.mainClass=example.Example

วิธีนี้gradle.buildสามารถเรียกใช้โครงการใดก็ได้

UPDATE: มีคำถามคล้าย ๆ กันว่า gradle เทียบเท่ากับปลั๊กอิน exec ของ maven สำหรับรันแอป Java คืออะไร? ถามมาก่อน แต่วิธีแก้ปัญหาแนะนำให้แก้ไขทุกโครงการbuild.gradle

package runclass;

public class RunClass {
    public static void main(String[] args) {
        System.out.println("app is running!");
    }
}

จากนั้นดำเนินการ gradle run -DmainClass=runclass.RunClass

:run FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':run'.
> No main class specified   

น่าจะซ้ำกันของstackoverflow.com/questions/16350757/…
Teresa Carrigan

ใช้คำสั่ง: gradle run
a_subscriber

คำตอบ:


138

ไม่มีทางเทียบเท่าโดยตรงกับmvn exec:javaใน gradle คุณต้องใช้applicationปลั๊กอินหรือมีJavaExecงาน

application เสียบเข้าไป

เปิดใช้งานปลั๊กอิน:

plugins {
    id 'application'
    ...
}

กำหนดค่าดังนี้:

application {
    mainClassName = project.hasProperty("mainClass") ? getProperty("mainClass") : "NULL"
}

ในบรรทัดคำสั่งให้เขียน

$ gradle -PmainClass=Boo run

JavaExec งาน

กำหนดงานสมมติว่าexecute:

task execute(type:JavaExec) {
   main = project.hasProperty("mainClass") ? getProperty("mainClass") : "NULL"
   classpath = sourceSets.main.runtimeClasspath
}

gradle -PmainClass=Boo executeในการทำงานเขียน คุณได้รับ

$ gradle -PmainClass=Boo execute
:compileJava
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes
:execute
I am BOO!

mainClassเป็นคุณสมบัติที่ส่งผ่านแบบไดนามิกที่บรรทัดคำสั่ง classpathถูกตั้งค่าให้ไปรับคลาสล่าสุด


หากคุณไม่ผ่านmainClassคุณสมบัติทั้งสองวิธีจะล้มเหลวตามที่คาดไว้

$ gradle execute

FAILURE: Build failed with an exception.

* Where:
Build file 'xxxx/build.gradle' line: 4

* What went wrong:
A problem occurred evaluating root project 'Foo'.
> Could not find property 'mainClass' on task ':execute'.

1
คุณมีการปรับเปลี่ยนbuild.gradleที่classpathจะ hardcoded จะรับจาวาเรียนจากbuild.gradle Java classpath แหล่งที่มา แม้ว่าคุณจะรันmvn exec:javaclasspath จะถูกตั้งค่าให้รับไฟล์ซอร์ส java ในไดเร็กทอรี maven ปัจจุบัน ในJavaExecงานฉันได้ทำเช่นเดียวกัน เปลี่ยนแหล่งที่มาjavaclasspathของคุณและเส้นทางของคลาสจะเปลี่ยนโดยอัตโนมัติ ไม่มี - เทียบเท่าคุณจำเป็นต้องใช้ปลั๊กอินหรือมีงาน mvn exec:javagradleapplicationJavaExec
First Zero

1
หรืออีกทางเลือกหนึ่งคือคุณเขียนปลั๊กอินของคุณเองเพื่อทำสิ่งนี้และถึงแม้คุณจะต้องเปลี่ยน build.gradle เพื่อรับปลั๊กอินของคุณ
ศูนย์แรก

3
ฉันเพิ่งลองสิ่งนี้และดูเหมือนว่าหลังจากเพิ่มtask execute(...เป็น build.gradle แล้วงานอื่น ๆ ทั้งหมดจะล้มเหลวด้วยข้อความแสดงข้อผิดพลาดเดียวกันที่บอกว่า gradle คาดว่า mainClass จะถูกส่งต่อไป ฉันไม่สามารถทำความสะอาดหรือสร้างได้
Nirro

4
@Nirei ทดแทนmain = mainClassด้วยmain = getProperty("mainClass")และจะไม่ตะโกนใส่คุณอีกต่อไป
Adi Gerber

2
สิ่งนี้ยังคงแตกgradle buildดูคำตอบของฉันด้านล่าง
Matt

140

คุณต้องใช้ปลั๊กอิน Gradle Application :

apply plugin:'application'
mainClassName = "org.gradle.sample.Main"

gradle runแล้วก็

ดังที่ Teresa ชี้ให้เห็นคุณยังสามารถกำหนดค่าmainClassNameเป็นคุณสมบัติของระบบและเรียกใช้ด้วยอาร์กิวเมนต์บรรทัดคำสั่ง


2
build.graldleที่จะต้องมีรหัสอย่างหนักทุกระดับดังกล่าวเข้าไป แต่ฉันมีโปรเจ็กต์ที่มีคลาส util มากมายซึ่งทุกคนมีเมธอดหลัก
Paul Verest

และคุณแน่ใจว่า 1) ชื่อคลาสแบบเต็มถูกต้อง 2) คุณใส่ชื่อคุณสมบัติที่ถูกต้องในไฟล์บิลด์ของคุณ - เช่น System.getProperty("mainClass") 3) ซอร์สโค้ดคือที่ที่ควรจะเป็นตามแบบแผน 4) มันใช้งานได้ทั้งหมด เมื่อคุณใส่RunClassไฟล์บิลด์
Vidya

ใช้ได้เฉพาะเมื่อbuild.gradleมีmainClassName = "runclass.RunClass". พารามิเตอร์-DmainClassไม่มีผล: gradle run -DmainClass=runclass.RunClass2รัน mainclass แบบฮาร์ดโค้ด
Paul Verest

3
หากคุณทำทั้งสองอย่าง (build file approach และ property approach) ฉันไม่รู้ว่าข้อใดมีความสำคัญมากกว่า คุณควรหาคำตอบนั้นหรือไม่ทำทั้งสองอย่างในการทดสอบของคุณ
Vidya

2
@PaulVerest นี่คือสิ่งที่ฉันทำ: ext.mainClass = project.hasProperty('mainClass') ? project.getProperty('mainClass') : 'org.gradle.sample.Main' ; apply plugin:'application' ; mainClassName = ext.mainClass ตอนนี้เมื่อคุณทำgradle -PmainClass=Foo runควรใช้Fooเป็นคลาสหลัก
msridhar

26

ขยายคำตอบของ First Zero ฉันเดาว่าคุณต้องการบางสิ่งที่คุณสามารถเรียกใช้gradle buildโดยไม่มีข้อผิดพลาด

ทั้งสองgradle buildและgradle -PmainClass=foo runAppทำงานกับสิ่งนี้:

task runApp(type:JavaExec) {
    classpath = sourceSets.main.runtimeClasspath

    main = project.hasProperty("mainClass") ? project.getProperty("mainClass") : "package.MyDefaultMain"
}

ที่คุณตั้งค่าคลาสหลักเริ่มต้นของคุณ


2
Imho นี่ควรเป็นคำตอบที่ยอมรับได้ การใช้วิธีของ FirstZero หรือ Vidya จะทำให้งานอื่น ๆ บ่นเนื่องจากไม่ได้ระบุคลาสหลัก
yanhan

วิธีการของ Matt ในการตั้งค่าหลักยังใช้ได้กับปลั๊กอินแอปพลิเคชัน ฉันใช้มันกับ Gradle Kotlin DSL: plugins { application }; application { mainClassName = if (project.hasProperty("mainClass")) project.properties.get("mainClass").toString() else "Foo" }
pvillela

@ Matt วิธีนี้แบ่งโปรแกรม Java ของฉันง่าย ๆ ที่ใช้ในการอ่านScanner nextLine()มีความคิดเกี่ยวกับการแก้ไขนี้หรือไม่? รับ "ไม่พบบรรทัด" เมื่อเรียกใช้โดยใช้ runApp
Greg Hilston

2
สำหรับทุกคนที่อ่านสิ่งนี้ในอนาคตฉันใช้ "standardInput = System.in` เพื่อให้การไล่ระดับสีของฉันยังคงส่งผ่านอินพุต
Greg Hilston

1

คุณสามารถกำหนดพารามิเตอร์และส่ง gradle clean build -Pprokey = goodbye

task choiceMyMainClass(type: JavaExec) {
     group = "Execution"
    description = "Run Option main class with JavaExecTask"
    classpath = sourceSets.main.runtimeClasspath

    if (project.hasProperty('prokey')){
        if (prokey == 'hello'){
            main = 'com.sam.home.HelloWorld'
        } 
        else if (prokey == 'goodbye'){
            main = 'com.sam.home.GoodBye'
        }
    } else {
            println 'Invalid value is enterrd';

       // println 'Invalid value is enterrd'+ project.prokey;
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.