2013-08-12 10 views
11

Co próbuję zrobić, to wykonać zadanie w build.gradle, które wykona główną klasę (klasa z główną metodą), ale nie wiem jak.Jak wykonać zadanie wywoływania głównej klasy?

Zrobiłem projekt testowy, aby przetestować, jak to zrobić. Oto układ struktury pliku:

testProject/ 
    build.gradle 
    src/main/groovy/hello/world/HelloWorld.groovy 

Oto treść build.gradle:

apply plugin: 'groovy' 
apply plugin: 'maven' 

repositories { 
    mavenCentral() 
} 

dependencies { 
    compile  'org.codehaus.groovy:groovy-all:2.0.6' 
} 

task(hello, dependsOn: jar, type: JavaExec) { 
    main = 'hello.world.HelloWorld' 
} 

Oto treść HelloWorld.groovy:

package hello.world 

class HelloWorld { 
    public static void main(String[] args) { 
     println "Hello World!" 
    } 
} 

Oto co ja get from shell:

testProject>$ gradle hello 
:compileJava UP-TO-DATE 
:compileGroovy UP-TO-DATE 
:processResources UP-TO-DATE 
:classes UP-TO-DATE 
:jar UP-TO-DATE 
:hello 
Error: Could not find or load main class hello.world.HelloWorld 
:hello FAILED 

FAILURE: Build failed with an exception. 

* What went wrong: 
Execution failed for task ':hello'. 
> Process 'command '/Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1 

* Try: 
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. 

BUILD FAILED 

Total time: 4.232 secs 

Moje pytanie brzmi: jak mogę wykonać gradle hello? Dziękuję Ci bardzo.

Odpowiedz

14

Po trochę googlowania znalazłem rozwiązanie. Jedyną rzeczą, którą muszę zmienić, jest blok zadań. Grupa Robocza jeden jest wklejony poniżej:

task(hello, dependsOn: jar, type: JavaExec) { 
    main = 'hello.world.HelloWorld' 
    classpath = sourceSets.main.runtimeClasspath 
} 
9

W tym celu jest application plugin.

apply plugin: 'application' 
mainClassName = 'hello.world.HelloWorld' 

a następnie zadzwonić

gradle run 

Oprócz dodawania run zadanie, stosując aplikacja wtyczki spowoduje również zmianę zachowania assemble zadania. Teraz utworzy samodzielną aplikację, którą można uruchomić za pomocą skryptu powłoki.

+0

Cóż, wszystko jest w porządku, jeśli chcę uruchomić tylko jedno zadanie. Co się stanie, jeśli mam wiele zadań z głównej klasy? – JBT

+0

Następnie należy użyć zadania JavaExec. –

+0

Znacznie łatwiejsze i bardziej eleganckie rozwiązanie niż zaakceptowana odpowiedź – kellyfj

2

Rozważmy build.gradle, który jest uproszczoną wersją:

apply plugin: 'groovy' 

task(hello, type: JavaExec) { 
    main = 'hello.world.HelloWorld' 
    classpath = files('exampleDir/bin','jars/groovy-all-2.0.1.jar') 
} 

Zanotuj 'classpath argument do zadania JavaExec. Wykorzystuje podkatalogów, takie jak:

exampleDir/src/hello/world/HelloWorld.groovy 
exampleDir/bin/hello/world/HelloWorld.class 
jars/groovy-all-2.0.1.jar 

gdzie:

(A) porywające wszystko-2.0.1.jar skopiowane z moim GROOVY_HOME/zabudowany

(B) HelloWorld.groovy są zbierane za pośrednictwem groovyc i jest następujący:

package hello.world 

class HelloWorld { 
    public static void main(String[] args) { 
     println "Hello World!" 
    } 
} 
+0

Dodałem następujący wiersz do bloku zadań hello: classpath = files (' build/libs/testProject.jar ',' build/classes/main "), który jest odpowiednikiem twojej ścieżki klas. Jednak to nie zadziałało. Zgłasza java.lang.NoClassDefFoundError: groovy/lang/GroovyObject. – JBT

+0

Inną kwestią, której nie lubię w twoim rozwiązaniu, jest ręczne zarządzanie zależnościami takimi jak groovy jar. – JBT

+0

W przypadku pierwszego komentarza dodanie w oczywisty sposób nie odpowiada ścieżce klasy w odpowiedzi. Jeśli HelloWorld.groovy jest skompilowany z groovyc, to słoik Groovy musi znajdować się w ścieżce klas, aby móc z niego korzystać. To prawda, że ​​natura manualna nie jest idealna, ale jest to oddzielna kwestia. –

0

Wystarczy określające sourceSets.main.runtimeClasspath jako ścieżka klasy może nie wystarczyć. Jeśli zobaczysz NoClassDefFoundError, może to pomóc:

task(hello, dependsOn: jar, type: JavaExec) { 
    main = 'hello.world.HelloWorld' 
    classpath(sourceSets.main.runtimeClasspath, sourceSets.main.compileClasspath) 
} 
Powiązane problemy