2012-01-25 34 views
29

File1.groovysceneggiatura carico dallo script Groovy

def method() { 
    println "test" 
} 

File2.groovy

method() 

voglio caricare/include le funzioni/metodi da File1.groovy durante il runtime, è uguale a rubys/rake's load. Sono in due diverse directory.

risposta

24

Se non ti dispiace il codice in file2 essere in un blocco with, si può fare:

new GroovyShell().parse(new File('file1.groovy')).with { 
    method() 
} 

Un altro metodo possibile sarebbe quello di cambio file1.groovy a:

class File1 { 
    def method() { 
    println "test" 
    } 
} 

E poi nel file2.groovy è possibile utilizzare mixin per aggiungere i metodi da file1

def script = new GroovyScriptEngine('.').with { 
    loadScriptByName('file1.groovy') 
} 
this.metaClass.mixin script 

method() 
+0

Ho usato il metaClass.mixin funziona perfettamente. Grazie – ptomasroos

+0

Un'altra domanda, una breve correlata. Se voglio eseguire uno script come previsto, lo script non è di classe. Non invocare un metodo. Lika esegue o esegue il metodo. – ptomasroos

+0

Probabilmente vuoi [GroovyShell.evaluate] (http://groovy.codehaus.org/api/groovy/lang/GroovyShell.html#evaluate (java.io.File)) –

11

È possibile valutare qualsiasi espressione o script in Groovy utilizzando GroovyShell.

File2.groovy

GroovyShell shell = new GroovyShell() 
def script = shell.parse(new File('/path/file1.groovy')) 
script.method() 
+0

fai a sapere se il suo possibile per ottenere i metodi, come nello script corrente. questo + = script. Se capisci. Questo è più quello che sto cercando. Il metodo di chiamata – ptomasroos

+1

è errato. dovrebbe essere script.invokeMethod ("metodo", args) assumendo che "metodo" sia statico. – codeDr

+0

Funziona bene per me. 'file1.groovy' non ha bisogno di essere una classe reale, né i suoi metodi sono statici. –

13

Sarà più facile se file1.groovy è una classe reale class File1 {...}.

Dato che, un altro modo per farlo è quello di caricare il file nella GroovyClassLoader:

this.class.classLoader.parseClass("src/File1.groovy") 

File1.method() 

File1.newInstance().anotherMethod() 
+2

puoi anche dire def script = this.class.classLoader.parseClass ("..."); def object = script.newInstance() – codeDr

+0

Sto usando anche questo (in Jenkins) e sembra che stia mangiando PermSpace. Vedi qui: http://stackoverflow.com/questions/24169976/understanding-groovy-grails-classloader-leak http://stackoverflow.com/questions/712187/troubleshooting-grails-groovy-memory-leaks Quindi mi chiedo se questo dovrebbe essere davvero raccomandato per le applicazioni server. –

+0

C'è una stranezza: sarebbe quindi meglio considerare un modo diverso di chiamare parseClass e usare quello con '.parseClass (new File (" .. "))' Vedi http://stackoverflow.com/questions/13993611/why-cant-i-instantate-a-groovy-class-from-another-groovy-class – Kuzeko

3

Ecco quello che sto usando.

1: Scrivere any_path_to_the_script.groovy come classe

2: Nello script di chiamata, l'uso:

def myClass = this.class.classLoader.parseClass(new File("any_path_to_the_script.groovy")) 
myClass.staticMethod() 

E 'di lavoro nella console sceneggiatura Jenkins Groovy. Non ho provato metodi non statici.

+0

(stesso commento di una risposta simile sopra) Sto usando anche questo (in Jenkins) e sembra che questo sia divorare PermSpace. Vedi qui: http://stackoverflow.com/questions/24169976/understanding-groovy-grails-classloader-leak http://stackoverflow.com/questions/712187/troubleshooting-grails-groovy-memory-leaks Quindi mi chiedo se questo dovrebbe essere davvero raccomandato per le applicazioni server. –

6

Sono in ritardo ma. Questo è il modo in cui abbiamo raggiunto ciò che stavi chiedendo. Così, ho un file1.gsh in questo modo:

File1:

println("this is a test script") 

def Sometask(param1, param2, param3) 
{ 
    retry(3){ 
     try{ 
      ///some code that uses the param 
     } 
     catch (error){ 
      println("Exception throw, will retry...") 
      sleep 30 
      errorHandler.call(error) 
     } 
    } 
} 

return this; 

E in un altro file, queste funzioni sono accessibili istanziando prima. Quindi in file2.

File2:

def somename 
somename = load 'path/to/file1.groovy' 
//the you can call the function in file1 as 

somename.Sometask(param1, param2, param3) 
+2

Funzionando perfettamente su un oleodotto Jenkins! (Nota: all'inizio avevo dimenticato il 'return this' alla fine del mio script, quindi' load' restituiva 'null'). – JonesV

+0

'load 'path/to/file'' funziona perfettamente, non so perché questo è stato così difficile da trovare, anche se ricordo male, non ha funzionato quando è stato prefisso con'./' –

+0

Cosa restituisce' this ' ? Dovrebbe essere come un oggetto Script o Sth nel fantastico SDK. (Ho già controllato l'oggetto 'Script' ma non c'è il metodo 'load' in esso.) – zgulser

Problemi correlati