1007
技術社區[雲棲]
《Groovy官方教程》Grape依賴管理器
1 快速入門
1.1添加一個依賴
Grape是一個內嵌在Groovy裏的Jar包依賴管理器。Grape讓你可以快速添加maven倉庫依賴到你的classpath裏,使腳本運行更加簡單。最簡單的一種用法是隻需要在你的腳本裏添加一個注解:
1 |
@Grab(group= 'org.springframework' , module= 'spring-orm' , version= '3.2.5.RELEASE' )
|
2 |
import org.springframework.jdbc.core.JdbcTemplate
|
@Grab也支持簡潔版:
1 |
@Grab( 'org.springframework:spring-orm:3.2.5.RELEASE' )
|
2 |
import org.springframework.jdbc.core.JdbcTemplate
|
注意,這裏我們用到了import,這是推薦的做法。當然你也可以在mvnrepository.com搜索到依賴包然後使用@Grab注解形式加到pom.xml實體裏。
1.2特定的倉庫
不是所有的依賴都在maven中心倉庫裏,你可以像下麵這樣添加新的倉庫:
2 |
@Grab(group= 'org.restlet' , module= 'org.restlet' , version= '1.1.6' )
|
1.3Maven分類器
有些maven依賴需要分類器才能解析,你可以這樣處理:
1 |
@Grab(group= 'net.sf.json-lib' , module= 'json-lib' , version= '2.2.3' , classifier= 'jdk15' )
|
1.4去除過渡依賴
有時你用到了一些過渡版本的依賴,它們可能和正式穩點版本有一點點差別,這時你想要將過渡依賴排除掉,你可以這樣寫:
1 |
@Grab( 'net.sourceforge.htmlunit:htmlunit:2.8' )
|
2 |
@GrabExclude( 'xml-apis:xml-apis' )
|
(譯者注:原文標題是Excluding Transitive Dependencies,譯者翻譯為過渡依賴。譯者理解為那些非穩定版本的依賴,如果讀者有更好的理解或翻譯請留言,謝謝)
1.5JDBC驅動
你可能需要加載JDBC驅動,因此你需要將JDBC驅動依賴添加到係統類加載器中,示例如下:
1 |
@GrabConfig(systemClassLoader=true) |
2 |
@Grab(group= 'mysql' , module= 'mysql-connector-java' , version= '5.1.6' )
|
1.6從Groovy Shell中使用Grape
通過groovysh使用grape需要調用一個變量:
1 |
groovy.grape.Grape.grab(group: 'org.springframework' , module: 'spring' , version: '2.5.6' )
|
1.7代理設置
如果因為防火牆,你可能需要一個代理服務器才能使用Groovy/Grape,你可以將代理服務器設置通過http.proxyHost和http.proxyPort係統屬性在命令行來設置:
1 |
groovy -Dhttp.proxyHost=yourproxy -Dhttp.proxyPort= 8080 yourscript.groovy
|
或者你也可以將其添加到JAVA_OPTS環境變量裏:
1 |
JAVA_OPTS = -Dhttp.proxyHost=yourproxy -Dhttp.proxyPort= 8080
|
1.8日誌
如果你想查看Grape的運行時狀態,可以通過設置係統屬性groovy.grape.report.downloads為true(比如說將-Dgroovy.grape.report.downloads=true添加JAVA_OPTS或調用它),Grape將會打印下麵的一些係統信息:
- 開始解析依賴
- 開始下載工件(原文為artifact,工件的意思)
- 重新下載工件
- 現在工件的時間和大小
如果要更加詳細的日誌,可以通過提高日誌級別(默認為-1),示例如下:
1 |
-Divy.message.logger.level= 4
|
2 詳細
Grape(The Groovy Adaptable Packaging Engine or Groovy Advanced Packaging Engine))是Groovy裏內嵌的一個基礎組件,通過grab()方法調用,一些類可以使用Ivy來打包成倉庫給Groovy用。這就支持開發者通過寫一段腳本來實現一些核心庫的需求。裝載這段腳本,Grape將會在運行時下載並鏈接所有依賴的庫。即便這些庫存在於Jcenter,Ibiblio和java.net
Grape遵從Ivy對模塊版本標識和命名轉換。
- group – 模塊屬於一個模塊組。對應Maven的groupId或者一個Ivy組織。任何匹配/groovy[x][\..*]^/的組都是被保留的,對於Groovy是有特定意義的。
- module – 加載的模塊名字,對應Mavne的artifactId或Ivy的artifact
- version – 模塊使用的版本號,要麼是字符串 ‘1.1-RC3’,要麼是Ivy的[2.2.1,)代表2.2.1或更高版本
- classifier – 可選的分類器,比如jdk15
3 用法
3.1 注解
可以在任何可以放注解的地方放一個或多個groovy.lang.Grab注解來告訴編譯器這段代碼依賴於特定的類庫。這個和添加類庫到Groovy編譯器的效果是一樣的。這個注解將會在任何其他類腳本的運行前被執行,也就是說類的導入可以通過添加@Grab注解來實現:
1 |
import com.jidesoft.swing.JideSplitButton
|
2 |
@Grab(group= 'com.jidesoft' , module= 'jide-oss' , version= '[2.2.1,2.3.0)' )
|
3 |
public class TestClassAnnotation {
|
4 |
public static String testMethod () {
|
5 |
return JideSplitButton. class .name
|
一個合適的grab(…)調用將會加在包含這個注解類的靜態初始化函數上(或者腳本元素)
3.2 多個Grape注解
如果需要在同一個節點使用一個注解多次可以使用@Grapes注解,比如說:
2 |
@Grab(group= 'commons-primitives' , module= 'commons-primitives' , version= '1.0' ),
|
3 |
@Grab(group= 'org.ccil.cowan.tagsoup' , module= 'tagsoup' , version= '0.9.7' )])
|
如果不這樣用的話,將會報這樣的錯:
1 |
Cannot specify duplicate annotation on the same member |
3.3 方法調用
一般地grab調用會在一個類或腳本初始化的時候進行。這可以確保groovy代碼依賴的庫在運行時都被類加載器加載進去。一種典型的調用如下:
1 |
import groovy.grape.Grape
|
2 |
// random maven library |
3 |
Grape.grab(group: 'com.jidesoft' , module: 'jide-oss' , version: '[2.2.0,)' )
|
4 |
Grape.grab([group: 'org.apache.ivy' , module: 'ivy' , version: '2.0.0-beta1' , conf:[ 'default' , 'optional' ]],
|
5 |
[group: 'org.apache.ant' , module: 'ant' , version: '1.7.0' ])
|
- 在同一個地方使用相同的參數多次調用grab是等價的,但是如果使用不同的類加載器可能需要重新運行
- 如果參數列表傳到grab調用有一個noExceptions參數,那麼將不會拋出參數
- grab需要一個rootLoader或GroovyClassLoader,也可以是調用類的類加載器鏈。默認情況下列的情形將會失敗並且拋出異常
- 通過classLoader傳遞的類加載器:參數和它的父類加載器
- 對象的加載器作為引用對象傳入,參數和它的父類加載器
- 類的類加載器調用grab
3.3.1 grab(HashMap)參數
- group: – – 模塊所屬的模塊組,對應Maven的groupId,任何匹配/groovy(|\..|x|x\..)/的組都是保留的,在Groovy模塊中有特殊用途
- module:– 要加載的模塊名,對應Maven的artifactId
- version:-也有可能是-使用的模塊版本號,要麼是字符串1.1-RC3要麼是Ivy Range [2.2.1,)表示2.2.1版本或更高版本
- classifier:–Maven解析的分類器
- conf:-,默認default’ – The configuration or scope of the module to download. The default conf is `default:映射到maven的runtime和master範圍
- force-默認是true,用於衝突時的修複,依賴於衝突管理器
- changing:-,默認是false,是否工件可以修改而不管版本的改變
- transitive:-,默認是true,是否解析其他依賴
grab有兩個基本變量,一個單個的map一個是帶一個map和多個依賴的map。調用單個map的grab和將一個相同的map傳入兩次調用是一樣的,因此grab參數和依賴可以混合在一個map裏,grab可以當成一個具有命名好參數的方法調用。
下麵的參數每組都是相同的意思,如果傳入多餘一個將是一個運行時錯誤
- group:, groupId:, organisation:, organization:, org:
- module:, artifactId:, artifact:
- version:, revision:, rev:
- conf:, scope:, configuration:
3.3.2 參數列表
- classLoader: – 或-解析jar包的類加載器
- refObject:–最近的父類加載器,可以作為加載器參數被傳遞
- validate:-,默認是false,是否驗證poms或ivy文件,或者是否直接信任緩存信息(默認false)
- noExceptions:-,默認是false,如果類加載器或參考查詢失敗,是否應該拋出異常或吞並異常(默認情況)
3.4 命令行工具
Grape增加了一個命令行來執行grape,可以用來檢視和管理本地grape緩存。
1 |
grape install <groupId> <artifactId> [<version>] |
這條命令會安裝特定的groovy模塊或maven工件,如果指定了版本,那麼將安裝特定的的版本,否則安裝最新的版本(類似我們傳遞 * 參數)
列出本地安裝的模塊(如果是groovy模塊,會顯示完整的maven名字)和版本
1 |
grape resolve (<groupId> <artifactId> <version>)+ |
返回安裝的模塊或工件的文件位置,並且會返回傳遞依賴模塊的位置。你可以傳入可選參數-ant,-dos,-shell中來得到ant腳本,windows批處理或unix shell腳本格式文件,-ivy將會得到類ivy格式的依賴
3.5 高級配置
3.5.1 倉庫目錄
如果你需要改變下載庫的grape目錄,可以使用grape.root係統屬性來改變默認值(默認值是~/.groovy/grape)
1 |
groovy -Dgrape.root=/repo/grape yourscript.groovy |
3.5.2 自定義Ivy設置
你可以自定義ivy的是指,通過創建一個~/.groovy/grapeConfig.xml文件,如果沒有這個文件,Grape會使用默認配置,詳細參考這裏。需要查找更多關於自定義設置的文檔,可以參考Ivy文檔。
3.6 更多示例
使用Apache Commons集合工具類
01 |
// create and use a primitive array list |
02 |
import org.apache.commons.collections.primitives.ArrayIntList
|
04 |
@Grab(group= 'commons-primitives' , module= 'commons-primitives' , version= '1.0' )
|
05 |
def createEmptyInts() { new ArrayIntList() }
|
07 |
def ints = createEmptyInts()
|
09 |
assert ints. size () == 1
|
10 |
assert ints. get ( 0 ) == 42
|
使用TagSoup
1 |
// find the PDF links of the Java specifications |
2 |
@Grab(group= 'org.ccil.cowan.tagsoup' , module= 'tagsoup' , version= '1.2.1' )
|
4 |
def parser = new XmlParser( new org.ccil.cowan.tagsoup.Parser())
|
7 |
html.body. '**' .a.@href. grep (~/.*\.pdf/). each { println it }
|
使用Google集合工具類
1 |
import com.google.common. collect .HashBiMap
|
2 |
@Grab(group= 'com.google.code.google-collections' , module= 'google-collect' , version= 'snapshot-20080530' )
|
3 |
def getFruit() { [grape: 'purple' , lemon: 'yellow' , orange: 'orange' ] as HashBiMap }
|
4 |
assert fruit.lemon == 'yellow'
|
5 |
assert fruit.inverse().yellow == 'lemon'
|
啟動Jetty服務器來運行Groovy模塊
02 |
@Grab(group= 'org.eclipse.jetty.aggregate' , module= 'jetty-server' , version= '8.1.7.v20120910' ),
|
03 |
@Grab(group= 'org.eclipse.jetty.aggregate' , module= 'jetty-servlet' , version= '8.1.7.v20120910' ),
|
04 |
@Grab(group= 'javax.servlet' , module= 'javax.servlet-api' , version= '3.0.1' )])
|
06 |
import org.eclipse.jetty.server.Server
|
07 |
import org.eclipse.jetty.servlet.*
|
08 |
import groovy.servlet.*
|
10 |
def runServer(duration) {
|
11 |
def server = new Server( 8080 )
|
12 |
def context = new ServletContextHandler(server, "/" , ServletContextHandler.SESSIONS);
|
13 |
context.resourceBase = "."
|
14 |
context.addServlet(TemplateServlet, "*.gsp" )
|
第一次啟動這個腳本的時候Grape會下載Jetty和它的依賴,並且會緩存它們。我們在8080端口創建了一個Jetty服務,並且將Groovy的TemplateServlet最為根服務。Groovy有自己強大的模板引擎機製。我們啟動這個服務並且運行一段時間。每次有人訪問https://localhost:8080/somepage.gsp的時候,它會顯示somepage.gsp給用戶,這些模板頁是放在一個相同的目錄下座位服務器腳本。
最後更新:2017-05-22 10:03:42