2010年10月11日

快快樂樂認識 Groovy 的 Grapes 及 grab()

Grape (The Groovy Adaptable Packaging Engine or Groovy Advanced Packaging Engine) is the infrastructure enabling the grab() calls in Groovy, a set of classes leveraging Ivy to allow for a repository driven module system for Groovy. This allows a developer to write a script with an essentially arbitrary library requirement, and ship just the script. Grape will, at runtime, download as needed and link the named libraries and all dependencies forming a transitive closure when the script is run from existing repositories such as Ibiblio, Codehaus, and java.net.
from http://groovy.codehaus.org/Grape

Grape是一項Groovy的提案(proposal),它用來解決Java長久以來令開發者困擾的一個問題「每次都要到處抓*.jar的函式庫套件」。

Grape的作法是提供一個Grab()方法,指定 groupId(group)、artifactId(module)、version 三個設定值,Groovy程式在執行時,會自動幫忙下載指定的函式庫檔案。

在不久之前,我們通常使用Maven來處理這麻煩事;但是在目前新的Groovy發行版,我們已經可以直接使用Grape的功能,它的實現方式是使用 @Grab 這個標記(annotation),我們直接在一段Groovy程式碼中,直接嵌入@Grab的宣告,不必透過其他軟體(只需要安裝好JDK、Groovy),就可以獨立完成指定的函式庫下載、再執行程式。

舉例來說,安裝好Groovy之後,我們使用 GroovyWS 寫一段 Web Services 的測試程式,需要引用 groovyx.net.ws.WSClient 這個類別。

很不幸地,預設安裝好的Groovy並沒有提供我們需要的套件,也就是缺少了 groovyws-0.5.2.jar 這個檔案。

以下的程式碼加入 @Grab ,再第一次執行的時候會比較慢一些,因為會自動下載 groovyws-0.5.2.jar 以及它相依的套件,第二次以後因為已經取得套件,就會略過直接執行。真的沒有看錯,除了指定版本的套件以外,連這個版本的套件所依賴的其他相關套件, Grape 也會一併幫我們下載。我想任何一個寫過稍微大一點的 Java 程式的人,都會清楚處理相依套件的麻煩,就像沒有yum工具的時代,需要到處找rpm檔案的那種痛苦。

@Grab(group='org.codehaus.groovy.modules', module='groovyws', version='0.5.2')
import groovyx.net.ws.WSClient

def proxy = new WSClient("http://localhost/api/SimpleTest.asmx?wsdl", this.class.classLoader)
proxy.initialize()

如果你堅持認為 @Grab 寫在程式碼裏面很礙眼,Grape也提供另一種選擇,也就是 grape 指令。它的格式如下:
grape install []

查詢已經安裝的套件可以用:
grape list

以剛才 GroovyWS 的例子來說,以下的 grape 指令能完成與 @Grab 相同的工作:
grape install 'org.codehaus.groovy.modules' 'groovyws' '0.5.2'
(這道指令實際上會自動下載數十個.jar檔案,相信我,你不會真的想要一個一個慢慢抓!!!)

因此,如果不想再程式碼裏面寫 @Grab 宣告,就可以把需要用到的套件,都用 grape 指令寫程 bash 或 batch 批次檔,讓我們在development或production階段都能自動完成相依套件的安裝,而不必東找西找還擔心漏掉其中一個。

另外一個好處就是,這些我們的程式需要用到的相關套件,並不必跟程式碼放在一起,Grape預設會把套件檔案都保存到 $USER_HOME/.groovy/grapes 這個資料夾,因此我們只需要維護自己寫的程式碼,而不必在lib資料夾中放一堆雜七雜八的*.jar檔案。

因此...
對於使用SVN管理的Java專案來說,不再需要把雜七雜八的一大堆*.jar檔案放到SVN repository,麻煩的事交給Grape就對了。
對於一個簡單的Groovy程式碼,只有一個檔案,但不小心引用很多個套件,只要簡單地放個 @Grab 宣告,就可以把它發佈出去,而不必夾帶一堆*.jar檔案,還要告訴End User如何設定正確的CLASSPATH。

2 則留言:

  1. 你好,我是想要學習groovy的新手,您的教學真是讓我非常驚艷,希望版主可以在多一些教學~~~我會隨時follow的!!

    回覆刪除
  2. Groovy是個好東西,對JVM Scripting語言有興趣的話,最近走紅的Scala也值得學習,都是用來簡化Java project的好東西。

    回覆刪除

lyhcode by lyhcode
歡迎轉載,請務必註明出處!