Gradle для виконання класу Java (без зміни build.gradle)


119

Існує простий плагін Eclipse для запуску Gradle, який просто використовує спосіб командного рядка для запуску gradle.

Що таке аналог gradle для компіляції та запуску Maven mvn compile exec:java -Dexec.mainClass=example.Example

Таким чином, будь-який проект з gradle.buildможе бути запущений.

ОНОВЛЕННЯ: Було подібне запитання: Що таке еквівалент градую модуля 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   


Використовуйте команду: gradle run
a_subscriber

Відповіді:


138

У mvn exec:javagradle немає прямого еквівалента , вам потрібно застосувати 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жорстке кодування для того, щоб забрати класи Java у вашого build.gradle класного джерела Java . Навіть під час запуску mvn exec:javaclasspath налаштовується на отримання вихідних файлів java у поточному каталозі Maven. У JavaExecзавданні я зробив те саме. Змініть джерело classpathдля вашого Java- коду, і шлях до класу зміниться автоматично. Немає mvn exec:javaеквівалента, gradleвам потрібно застосувати applicationплагін або мати JavaExecзавдання.
Перший нуль

1
АЛЕ інший варіант - ви пишете власний плагін для цього, і навіть тоді вам доведеться змінити build.gradle, щоб забрати свій плагін.
Перша нуль

3
Я тільки що спробував це, і, здається, що після додавання task execute(...до build.gradle, будь-яке інше завдання не вдається з тим самим повідомленням про помилку, яке говорить про те, що gradle очікує передачі mainClass. Я не можу чистити чи будувати.
Nirro

4
Чи не @Nirei Заміни main = mainClassз , main = getProperty("mainClass")і він більше не буде кричати на вас.
Аді Гербер

2
це все ще ламається gradle build, дивіться мою відповідь нижче.
Метт

140

Вам просто потрібно використовувати плагін додатка Gradle :

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

І то просто gradle run.

Як вказує Тереза, ви також можете налаштувати mainClassNameяк властивість системи та запустити аргумент командного рядка.


2
Це вимагатиме жорсткого кодування кожного такого класу build.graldle. Але у мене є проект з великою кількістю утильних класів, у яких кожен має основний метод.
Пол Верест

І ви впевнені: 1) повністю кваліфіковане ім'я класу правильне; 2) ви вводите потрібне ім'я властивості у свій файл збирання - наприклад System.getProperty("mainClass") , 3) вихідний код є там, де він повинен бути згідно з умовами, 4) це все працює коли ви ставите RunClassу файл збірки?
Видя

Він працює тільки якщо build.gradleє mainClassName = "runclass.RunClass". Параметр-DmainClass не впливає: gradle run -DmainClass=runclass.RunClass2виконує жорстко закодований основний клас.
Пол Верест

3
Якщо ви робите обидва (підхід до побудови файлів та підхід властивості), я фактично не знаю, який має перевагу. Вам слід або знайти цю відповідь, або не робити обох у своєму тестуванні.
Видя

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як основний клас.
мсрідхар

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
Імхо, це повинна бути прийнята відповідь. Використання методу FirstZero або Vidya спричинить скарги на інші завдання через те, що основний клас не визначений.
Янхань

Підхід Метта до встановлення основного значення також працює для додатка додатка. Я використовую його з DSL Gradle Kotlin: plugins { application }; application { mainClassName = if (project.hasProperty("mainClass")) project.properties.get("mainClass").toString() else "Foo" }
pvillela

@Matt Цей підхід порушує мою просту програму Java, яка використовує Scannerдля читання nextLine(). Будь-яка думка на виправлення цього? Продовжуйте отримувати "жодну лінію не знайдено" під час запуску за допомогою runApp.
Грег Хілстон

2
Щоб хтось читав це в майбутньому, я використав `standardInput = System.in`, щоб дозволити моєму виконанню виконання градусів все-таки пройти вхід
Грег Гілстон

0

Ви можете його параметризувати і пройти 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;
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.