Gradle per eseguire la classe Java (senza modificare build.gradle)


119

Esiste un semplice plug-in Eclipse per eseguire Gradle, che utilizza solo il modo della riga di comando per avviare Gradle.

Cos'è l'analogo gradle per compilare ed eseguire Maven mvn compile exec:java -Dexec.mainClass=example.Example

In questo modo qualsiasi progetto con gradle.buildpotrebbe essere eseguito.

AGGIORNAMENTO: C'era una domanda simile Qual è l'equivalente gradle del plug-in exec di Maven per l'esecuzione di app Java? chiesto prima, ma la soluzione suggeriva di modificare ogni progettobuild.gradle

package runclass;

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

Quindi esecuzione 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   


Usa il comando: gradle run
— a_subscriber

Risposte:


138

Non esiste un equivalente diretto a mvn exec:javain gradle, è necessario applicare il applicationplug-in o avere JavaExecun'attività.

application collegare

Attiva il plugin:

plugins {
    id 'application'
    ...
}

Configuralo come segue:

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

Sulla riga di comando, scrivi

$ gradle -PmainClass=Boo run

JavaExec compito

Definisci un'attività, diciamo execute:

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

Per correre scrivi gradle -PmainClass=Boo execute. Ottieni

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

mainClassè una proprietà passata dinamicamente dalla riga di comando. classpathè impostato per riprendere le lezioni più recenti.


Se non si passa nella mainClassproprietà, entrambi gli approcci falliscono come previsto.

$ 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
Devi modificare build.gradle, classpathè hardcoded per prendere le classi java dal tuo classpath build.gradle java source. Anche quando esegui mvn exec:javail classpath è impostato per raccogliere i file di origine java nella directory maven corrente. Nel JavaExeccompito, ho fatto lo stesso. Cambia il classpathper la tua sorgente java e il percorso della classe cambierà automaticamente. Non è necessario applicare il plug-in o eseguire un'attività mvn exec:javaequivalente . gradleapplicationJavaExec
— Primo zero

1
O l'altra opzione è che scrivi il tuo plug-in per farlo e anche allora devi cambiare build.gradle per prendere il tuo plug-in.
— Primo zero

3
L'ho appena provato e sembra che dopo l'aggiunta task execute(...a build.gradle, ogni altra attività fallisca con lo stesso messaggio di errore che dice che gradle si aspetta che mainClass venga passato. Non posso pulire o costruire.
— Nirro

4
@Nirei Sostituisci main = mainClasscon main = getProperty("mainClass")e non ti sgriderà più.
— Adi Gerber

2
questo si rompe ancora gradle build, vedi la mia risposta di seguito.
— Matt

140

Hai solo bisogno di utilizzare il plug-in dell'applicazione Gradle :

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

E poi semplicemente gradle run.

Come sottolinea Teresa, puoi anche configurare mainClassNamecome proprietà di sistema ed eseguire con un argomento della riga di comando.


2
Ciò richiederebbe di codificare in modo rigido ogni classe di questo tipo build.graldle. Ma ho un progetto con molte classi di utilità, ognuna con un metodo principale.
— Paul Verest

E sei sicuro che 1) il nome della classe completo sia corretto 2) metti il ​​nome della proprietà corretto nel tuo file di build - ad esempio System.getProperty("mainClass") , 3) il codice sorgente è dove dovrebbe essere secondo la convenzione, 4) funziona tutto quando metti RunClassnel file build?
— Vidya

Funziona solo se lo build.gradleha mainClassName = "runclass.RunClass". Il parametro -DmainClassnon ha effetto: gradle run -DmainClass=runclass.RunClass2esegue la classe principale hardcoded.
— Paul Verest

3
Se si esegue entrambe le operazioni (approccio basato su file e approccio alla proprietà), in realtà non so quale abbia la precedenza. Dovresti trovare quella risposta o non fare entrambe le cose nel tuo test.
— Vidya

2
@PaulVerest Ecco cosa ho fatto: ext.mainClass = project.hasProperty('mainClass') ? project.getProperty('mainClass') : 'org.gradle.sample.Main' ; apply plugin:'application' ; mainClassName = ext.mainClass ora, quando lo fai gradle -PmainClass=Foo run, dovresti usarlo Foocome classe principale.
— msridhar

26

Espandendo la risposta di First Zero, immagino che tu voglia qualcosa in cui puoi anche eseguire gradle buildsenza errori.

Entrambi gradle builde gradle -PmainClass=foo runApplavora con questo:

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

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

dove imposti la tua classe principale predefinita.


2
Imho questa dovrebbe essere la risposta accettata. L'uso del metodo di FirstZero o di Vidya provocherà il reclamo di altre attività a causa della mancata specificazione della classe principale.
— yanhan

L'approccio di Matt all'impostazione del valore principale funziona anche per il plug-in dell'applicazione. Lo sto usando con il Gradle Kotlin DSL: plugins { application }; application { mainClassName = if (project.hasProperty("mainClass")) project.properties.get("mainClass").toString() else "Foo" }
— pvillela

@Matt Questo approccio rompe il mio semplice programma Java che utilizza a Scannerper leggere nextLine(). Qualche pensiero su una soluzione per questo? Continua a ricevere "nessuna linea trovata" durante l'esecuzione utilizzando runApp.
— Greg Hilston

2
Per chiunque legga questo in futuro, ho usato `standardInput = System.in` per consentire alla mia esecuzione gradle di passare ancora in input
— Greg Hilston

0

Puoi parametrizzarlo e passare 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;
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.