2012-12-07 13 views
5

Voglio eseguire uno script di riga di comando groovy dal mio script di compilazione Gradle.Esecuzione di script Groovy da Gradle utilizzando GroovyShell: Eccezione nel thread "main" java.lang.NoClassDefFoundError: org/apache/commons/cli/ParseException

sto usando questo codice nel mio script Gradle:

def groovyShell = new GroovyShell(); 
groovyShell.run(file('script.groovy'), ['arg1', 'arg2'] as String[]) 

Le cose funzionano bene fino a quando il mio script Groovy (script.groovy) utilizza la classe CliBuilder. Allora ottengo la seguente eccezione:

org.codehaus.groovy.runtime.InvokerInvocationException: java.lang.NoClassDefFoundError: org/apache/commons/cli/ParseException ... Caused by: java.lang.ClassNotFoundException: org.apache.commons.cli.ParseException

ho trovato un sacco di persone con problemi ed errori simili, ma "la soluzione" era difficile da estrarre dai numerosi messaggi che ho letto. Un sacco di persone suggerivano di mettere il vaso commons-cli sul classpath, ma farlo per GroovyShell non mi era affatto chiaro. Inoltre, avevo già dichiarato @Grapes e @Grab per le mie librerie richieste nello script.groovy, quindi dovrebbe avere tutto ciò di cui aveva bisogno.

risposta

7

Grazie a this unaccepted SO answer, ho finalmente trovato quello che dovevo fare:

//define our own configuration 
configurations{ 
    addToClassLoader 
} 
//List the dependencies that our shell scripts will require in their classLoader: 
dependencies { 
    addToClassLoader group: 'commons-cli', name: 'commons-cli', version: '1.2' 
} 
//Now add those dependencies to the root classLoader: 
URLClassLoader loader = GroovyObject.class.classLoader 
configurations.addToClassLoader.each {File file -> 
    loader.addURL(file.toURL()) 
} 

//And now no more exception when I run this: 
def groovyShell = new GroovyShell(); 
groovyShell.run(file('script.groovy'), ['arg1', 'arg2'] as String[]) 

Potete trovare maggiori dettagli su classloader e il motivo per cui questa soluzione funziona in this forum post.

Happy scripting!

(Prima che mi downvote per aver risposto alla mia domanda, read this)

+0

Questo hack non dovrebbe essere richiesto per risolvere il tuo problema. Il post sul forum a cui ci si collega è diverso in quanto ha a che fare con le peculiarità di caricamento della classe di 'java.sql.DriverManager'. –

+0

Sono d'accordo che non dovrebbe essere necessario @PeterNiederwieser in base alla mia comprensione limitata di classLoaders! Tuttavia, è l'unico modo che ho trovato per farlo funzionare. Ho commentato più in basso nella risposta di Hiery: http://stackoverflow.com/questions/13763112/running-groovy-script-from-gradle-using-groovyshell-exception-in-thread-main#comment18958559_13763451 – Taytay

+0

Né tuo né Hiery Nomus le risposte funzionano ancora, ma il problema è ancora lì. Qualunque cosa fosse in precedenza "configurations.addToClassLoader", non esiste più. Non capisco esattamente quali classi ha dovuto caricare. – wvxvw

2

L'alternativa per fare questo è il seguente:

buildScript { 
    repositories { mavenCentral() } 
    dependencies { 
    classpath "commons-cli:commons-cli:1.2" 
    } 
} 

def groovyShell = new GroovyShell() 
.... 

questo mette la dipendenza comuni-CLI nel classpath di il buildscript invece del classpath del progetto da costruire.

+1

Questo dovrebbe funzionare fintanto che viene usato insieme a 'new GroovyShell (buildScript.classLoader)'. –

+0

Grazie per la risposta e i commenti! Mi sono emozionato quando ho letto questo, pensando di aver appena perso l'ovvio. Tuttavia, ho provato di nuovo, solo per essere sicuro, e non funziona. (Whoops - inviato troppo presto. Sto modificando questo commento ora ...) – Taytay

+0

Questa risposta mi è sembrata familiare poiché sono abbastanza sicuro che ho seguito questa strada. Ho provato di nuovo, solo per essere sicuro, e non funziona. :(Peter, ho effettivamente usato il "nuovo GroovyShell (buildscript.classloader)" dopo aver dichiarato una dipendenza come suggerito da Hiery. Dopo le mie ore di "sperimentazione" l'altro giorno, sono propenso a pensare che questo abbia qualcosa a che fare con il nativo di Groovy dipendenza, e inclusione, su alcuni pezzi del commons-cli, come CliBuilder, ma non tutto.ammetto che questo è sopra la mia testa, e dovrebbe essere più semplice di quello che ho fatto :) :) – Taytay

Problemi correlati