http://groovy.codehaus.org/Grape
Quick Start(快速开始)
Grape lets you quickly add maven repository dependencies to your classpath. Here are the most common solutions:
Grape让你快速的添加maven库依赖到classpath,下面是一些通用的解决方案:
Add a Dependency(添加一个依赖)
@Grab(group='org.springframework', module='spring', version='2.5.6')
import org.springframework.jdbc.core.JdbcTemplate
Yes, you can annotate an import in Groovy. You can also search for dependencies on mvnrepository.com and it will provide you the @Grab annotation form of the pom.xml entry.
是的,在Groovy中你可以注解一个import 。你也可以在 mvnrepository.com 搜索下依赖,它会为pom.xm提供@Grab注解的格式。
Specify Additional Repositories(指定额外的依赖库)
Not all dependencies are in maven central. You can add new ones like this:
并不是所有的依赖都在maven中心,你可以像这样添加依赖:
@GrabResolver(name='restlet', root='http://maven.restlet.org/')
@Grab(group='org.restlet', module='org.restlet', version='1.1.6')
Maven Classifiers(Maven 分级器)
Some maven dependencies need classifiers in order to be able to resolve. You can fix that like this:
一些依赖库需要添加classifiers以保证能够解析,可以这样来修正:
@Grab(group='net.sf.json-lib', module='json-lib', version='2.2.3', classifier='jdk15')
Excluding Transitive Dependencies(排除过渡性依赖)
Sometimes you will want to exclude transitive dependencies as you might be already using a slightly different but compatible version of some artifact. You can do this as follows:
有时你需要排除一些过渡性的依赖由于你可能已经用了一个稍微不一样的但可兼容的版本(的构件)。你可以像下面这样做:
@Grab('net.sourceforge.htmlunit:htmlunit:2.8')
@GrabExclude('xml-apis:xml-apis')
JDBC Drivers(JDBC驱动)
Because of the way JDBC drivers are loaded, you'll need to configure Grape to attach JDBC driver dependencies to the system class loader. I.e:
由于JDBC驱动类的加载方式,你需要配置一下Grape来添加JDBC驱动依赖附加到 system class loader。例如:
@GrabConfig(systemClassLoader=true)
@Grab(group='mysql', module='mysql-connector-java', version='5.1.6')
Using Grape From the Groovy Shell(在Groovy Shell中运用Grape)
From groovysh use the method call variant:
在groovysh中用方法调用
groovy.grape.Grape.grab([group:'org.springframework', module:'spring', version:'2.5.6'])
Proxy settings(代理设置)
If you are behind a firewall and/or need to use Groovy/Grape through a proxy server, you can specify those settings on the command like via the http.proxyHost and http.proxyPort system properties:
如果你使用了防火墙,或者需要通过一个代理服务器来用Groovy/Grape,那么你可以指定一些设置于命令行上,比如说通过 http.proxyHost和http.proxyPort等系统属性(system properties)。
groovy -Dhttp.proxyHost=yourproxy -Dhttp.proxyPort=8080 yourscript.groovy
Or you can make this system wide by adding these properties to your JAVA_OPTS environment variable:
或者你可以让它作用于整个系统范围,通过添加这些属性到你的JAVA_OPTS环境变量上:
JAVA_OPTS = -Dhttp.proxyHost=yourproxy -Dhttp.proxyPort=8080
Detail(细节)
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.
Groovy适配包装引擎或Groovy高级包装引擎是在Groovy中启用grab()调用的基础架构,是一套虑及Groovy库驱动模块系统的classes leveraging Ivy。它允许开发人员编写本质上需要任意库依赖的脚本。当脚本运行自已经存在的库时(如 Ibiblio, Codehaus, and java.net等),Grape会在运行时期按需下载并将已命名库与所有依赖连接成可传递的闭包。
Grape follows the Ivy conventions for module version identification, with naming change.
Grape遵循Ivy约定中的模块版本定义,with naming change(是包括naming change?还是说命名改变了)。
-
group
- Which module group the module comes from. Translates directly to a Maven groupId or an Ivy Organization. Any group matching /groovy[x][\..*]^/
is reserved and may have special meaning to the groovy endorsed modules. -
module
- The name of the module to load. Translated directly to a Maven artifactId or an Ivy artifact. -
version
- The version of the module to use. Either a literal version '1.1-RC3' or an Ivy Range '[2.2.1,)' meaning 2.2.1 or any greater version).
The downloaded modules will be stored according to Ivy's standard mechanism with a cache root of ~/.groovy/grape
下载的模块将会按照标准的机制保存在一个缓存目录:
~/.groovy/grape
Usage(用法)
Annotation(注解)
One or more groovy.lang.Grab annotations can be added at any place that annotations are accepted to tell the compiler that this code relies on the specific library. This will have the effect of adding the library to the classloader of the groovy compiler. This annotation is detected and evaluated before any other resolution of classes in the script, so imported classes can be properly resolved by a @Grab annotation.
一个或多个groovy.lang.Grab注解可以添加到注解可接收的地方来告诉编译器这些代码依赖于指定的库。这将起到给groovy编辑器的类加载器添加库的效果。此注解将会在代码中的其它类型解决方案之前被检测到并求值。因此引用类可以通过一个@Grab注解得到恰当的解决。
import com.jidesoft.swing.JideSplitButton
@Grab(group='com.jidesoft', module='jide-oss', version='[2.2.1,2.3.0)')
public class TestClassAnnotation {
public static String testMethod () {
return JideSplitButton.class.name
}
}
An appropriate grab(...)
call will be added to the static initializer of the class of the containing class (or script class in the case of an annotated script element).
一个适当的grab(...)调用当会添加到类初始化器。
Multiple Grape Annotations(多个Grap注解)
In order to use a Grape annotation multiple times you must use the Grapes annotation, e.g.:
要用多次Grape注解,你必须用Grapes注解,如:
@Grapes([
@Grab(group='commons-primitives', module='commons-primitives', version='1.0'),
@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7')])
class Example {
// ...
}
Otherwise you'll encounter the following error:
否则你将会遇到如下错误:
Cannot specify duplicate annotation on the same member
Method call(方法调用)
Typically a call to grab will occur early in the script or in class initialization. This is to insure that the libraries are made available to the ClassLoader before the groovy code relies on the code. A couple of typical calls may appear as follows:
往往一个grab的调用会发生在脚本或类初始化之前,这是为了保证在grooy代码依赖之前使得这些库对类加载器来说可用。下面是几个典型的调用:
import groovy.grape.Grape
// random maven library
Grape.grab(group:'com.jidesoft', module:'jide-oss', version:'[2.2.0,)')
Grape.grab([group:'org.apache.ivy', module:'ivy', version:'2.0.0-beta1', conf:['default', 'optional']],
[group:'org.apache.ant', module:'ant', version:'1.7.0'])
// endorsed Groovy Module
// FUTURE grab('Scriptom')
* Multiple calls to grab in the same context with the same parameters should be idempotent. However, if the same code is called with a different ClassLoader context then resolution may be re-run.
相同Context下,以相同参数多次对grab的调用应该是幂等的(结果相同)。然而,如果相同的代码被不同的 ClassLoader context 调用,那么解决方案可能会重新运行。
-
grab
is disabled by default. Starting calling Grape.initGrape()
will enable grab. Any calls to grab beforeinitGrape()
is called will be ignored. Hence Grape managed classloading is opt in only. Multiple calls tiGrape.initGrape()
after the first successful call are ignored. - If the
args
map passed into the grab
call has an attribute noExceptions
that evaluates true no exceptions will be thrown. -
grab
requires that a RootLoader or GroovyClassLoader be specified or be in the ClassLoader chain of the calling class. By default failure to have such a ClassLoader available will result in module resolution and an exception being thrown (if initGrape()
has been called).
- The ClassLoader passed in via the
classLoader:
argument and it's parent classloaders. - The ClassLoader of the object passed in as the
referenceObject:
argument, and it's parent classloaders. - The ClassLoader of the class issuing the call to
grab
grab(HashMap)
Parameters(参数)
-
group:
- <String> - Which module group the module comes from. Translates directly to a Maven groupId. Any group matching /groovy(
|x\..
)/
is reserved and may have special meaning to the groovy endorsed modules. -
module:
- <String> - The name of the module to load. Translated directly to a Maven artifactId. -
version:
- <String> and possibly <Range> - The version of the module to use. Either a literal version '1.1-RC3' or an Ivy Range '[2.2.1,)' meaning 2.2.1 or any greater version). -
classifier:
- <String> - The Maven classifier to resolve by. -
conf:
- <String>, default 'default' - The configuration or scope of the module to download. The default conf isdefault:
which maps to the maven runtime
and master
scopes. -
force:
- <boolean>, defaults true - Used to indicate that this revision must be used in case of conflicts, independently of conflicts manager -
changing:
- <boolean>, default false - Whether the artifact can change without it's version designation changing. -
transitive:
- <boolean>, default true - Whether to resolve other dependencies this module has or not.
-
group:
- <String> - 模块所属组,将会直接翻译为Maven groupId.任何匹配 /groovy(
|x\..
)/(正则表达式)
的组名将被保留,它可能对groovy授权的模块有特定意义。 -
module:
- <String> - 要加载模块的名称,将会被直接翻译为Maven artifactId。 -
version:
- <String> and possibly <Range> - 模块要用的版本,可以是一个文字版本号‘ 1.1-RC3 ’或一个Ivy版本范围‘ '[2.2.1,) ’(表示2.2.1或任意更高的版本)。 -
classifier:
- <String> - 指定 Maven classifier。 -
conf:
- <String>, default 'default' -模块下载的作用域配置。默认为default
映射到Maven的runtime
和master
作用域 . -
force:
- <boolean>, defaults true - 是否强制使用指定的版本,以防腐剂冲突或独立于冲突管理器之外。 -
changing:
- <boolean>, default false - 构件是否可以改变并不改变版本号 -
transitive:
- <boolean>, default true - 是否解决传递性依赖。
There are two principal variants of grab
, one with a single Map and one with an arguments Map and multiple dependencies map. A call to the single map grab is the same as calling grab with the same map passed in twice, so grab arguments and dependencies can be mixed in the same map, and grab can be called as a single method with named parameters.
grab有两个主要的变体,一个是带单个map,另一个是带一个参数map和多个依赖map。单map grab的调用相当于同一个map传递两次,因此grab的参数及依赖可以混合到一个map里,从而一个grab可以以一个带命名参数的方法来调用。
There are synonyms for these parameters. Submitting more than one is a runtime exception.
这些参数的名字是有同义词的,提交多个同义的参数将有产生运行时异常。
-
group:
, groupId:
, organisation:
, organization:
, org:
-
module:
, artifactId:
, artifact:
-
version:
, revision:
, rev:
-
conf:
, scope:
, configuration:
Arguments Map arguments
-
classLoader:
- <GroovyClassLaoder> or <RootClassLoader> - The ClassLoader to add resolved Jars to -
refObject:
- <Object> - The closest parent ClassLoader for the object's class will be treated as though it were passed in as classLoader:
-
validate:
- <boolean>, default false - Should poms or ivy files be validated (true), or should we trust the cache (false). -
noExceptions:
- <boolean>, default false - If ClassLoader resolution or repository querying fails, should we throw an exception (false) or fail silently (true).
Command Line Tool(命令行工具)
Grape added a command line executable 'grape' that allows for the inspection and management of the local grape cache.
Grape添加了一个命令行执行程序‘grape’,可以用来查看和管理本地的grape缓存。
grape install <groupId> <artifactId> [<version>]
This installs the specified groovy module or maven artifact. If a version is specified that specific version will be installed, otherwise the most recent version will be used (as if '*' we passed in).
这将会安装一个指定的groovy模块或maven构件,如果指定了版本的话,将会安装指定的版本,否则会用最近的版本(我们传一个‘*’的话也同样)。
grape list
Lists locally installed modules (with their full maven name in the case of groovy modules) and versions.
列出本地已经安装的模块(如果是groovy模块的话将会带着它们的全maven名)及版本。
grape resolve (<groupId> <artifactId> <version>)+
This returns the file locations of the jars representing the artifcats for the specified module(s) and the respective transitive dependencies. You may optionally pass in -ant, -dos, or -shell to get the dependencies expressed in a format applicable for an ant script, windows batch file, or unix shell script respectively. -ivy may be passed to see the dependencies expressed in an ivy like format.
这将列返回指定模块的构件路径及其传递性依赖,你可以任意的传递-ant,-dos,或-shell来分别得到该依赖的ant脚本,windows批处理文件,或unix shell脚本。传递-ivy可以看到该依赖的类ivy格式。
Advanced configuration(高级配置)
Repository Directory(库目录)
If you need to change the directory grape uses for downloading libraries you can specify the grape.root system property to change the default (which is ~/.groovy/grape)
如果需要改变grape的库下载目录,你可以指定grape.root系统属性来改变默认值(默认值为‘~/.groovy/grape’)
groovy -Dgrape.root=/repo/grape yourscript.groovy
Customize Ivy settings(自定义Ivy设置)
//TODO expand on discussion of grapeConfig.xml
You can customize the ivy settings that Grape uses by creating a ~/.groovy/grapeConfig.xml file. If no such file exists,here are the default settings used by Grape:
你可以通过创建一个~/.groovy/grapeConfig.xml文件来自定义ivy的设置。如果此文件不存在,Grape将会默认用这个设置。
<ivysettings>
<settings defaultResolver="downloadGrapes"/>
<resolvers>
<chain name="downloadGrapes">
<filesystem name="cachedGrapes">
<ivy pattern="${user.home}/.groovy/grapes/[organisation]/[module]/ivy-[revision].xml"/>
<artifact pattern="${user.home}/.groovy/grapes/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/>
</filesystem>
<!-- todo add 'endorsed groovy extensions' resolver here -->
<ibiblio name="codehaus" root="http://repository.codehaus.org/" m2compatible="true"/>
<ibiblio name="ibiblio" m2compatible="true"/>
<ibiblio name="java.net2" root="http://download.java.net/maven/2/" m2compatible="true"/>
</chain>
</resolvers>
</ivysettings>
For more information on how to customize these settings, please refer to the Ivy documentation.
关于如何自定义配置的更多信息,请参考:Ivy文档
Add your local Maven2 repository(添加本地Maven库)
If you find yourself wanting to reuse artifacts that you already have locally in your Maven2 repository, then you can add this line to your ~/.groovy/grapeConfig.xml:
如果想要重用你的Maven2本地仓库中的构件的话,你可以将这行内容添加到你的 ~/.groovy/grapeConfig.xml中:
<ibiblio name="local" root="file:${user.home}/.m2/repository/" m2compatible="true"/>
And further customize your Grape configuration:
<?xml version="1.0"?>
<ivysettings>
<settings defaultResolver="downloadGrapes"/>
<resolvers>
<chain name="downloadGrapes">
<!-- todo add 'endorsed groovy extensions' resolver here -->
<ibiblio name="local" root="file:${user.home}/.m2/repository/" m2compatible="true"/>
<filesystem name="cachedGrapes">
<ivy pattern="${user.home}/.groovy/grapes/[organisation]/[module]/ivy-[revision].xml"/>
<artifact pattern="${user.home}/.groovy/grapes/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/>
</filesystem>
<ibiblio name="codehaus" root="http://repository.codehaus.org/" m2compatible="true"/>
<ibiblio name="ibiblio" m2compatible="true"/>
<ibiblio name="java.net2" root="http://download.java.net/maven/2/" m2compatible="true"/>
</chain>
</resolvers>
</ivysettings>
More Examples(更多示例)
Using Apache Commons Collections:
// create and use a primitive array
import org.apache.commons.collections.primitives.ArrayIntList
@Grab(group='commons-primitives', module='commons-primitives', version='1.0')
def createEmptyInts() { new ArrayIntList() }
def ints = createEmptyInts()
ints.add(0, 42)
assert ints.size() == 1
assert ints.get(0) == 42
Using TagSoup:
// find the PDF links in the Java 1.5.0 documentation
@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7')
def getHtml() {
def parser = new XmlParser(new org.ccil.cowan.tagsoup.Parser())
parser.parse("http://java.sun.com/j2se/1.5.0/download-pdf.html")
}
html.body.'**'.a.@href.grep(~/.*\.pdf/).each{ println it }
Using Google Collections:
// Google Collections example
import com.google.common.collect.HashBiMap
@Grab(group='com.google.code.google-collections', module='google-collect', version='snapshot-20080530')
def getFruit() { [grape:'purple', lemon:'yellow', orange:'orange'] as HashBiMap }
assert fruit.lemon == 'yellow'
assert fruit.inverse().yellow == 'lemon'
Launching a Jetty server to server Groovy templates:
import org.mortbay.jetty.Server
import org.mortbay.jetty.servlet.*
import groovy.servlet.*
@Grab(group = 'org.mortbay.jetty', module = 'jetty-embedded', version = '6.1.0')
def runServer(duration) {
def server = new Server(8080)
def context = new Context(server, "/", Context.SESSIONS);
context.resourceBase = "."
context.addServlet(TemplateServlet, "*.gsp")
server.start()
sleep duration
server.stop()
}
runServer(10000)
Grape will download Jetty and its dependencies on first launch of this script, and cache them. We're creating a new Jetty Server on port 8080, then expose Groovy's TemplateServlet at the root of the context — Groovy comes with its own powerful template engine mechanism. We start the server and let it run for a certain duration. Each time someone will hithttp://localhost:8080/somepage.gsp, it will display the somepage.gsp template to the user — those template pages should be situated in the same directory as this server script.
Grape将会在第一次启动本脚本时下载Jetty及其依赖,并缓存之。我们会在端口8080创建一个Jetty服务,然后开放context根下的Grooy的TemplateServlet(Grooy自带的一个强大的模板引擎机制)。我们启动服务并保持其运行一段特定的时间,每当有人访问http://localhost:8080/somepage.gsp,它将为用户显示somepage.gsp模板(这些模板文件将和此服务脚本位于相同的目录)。
http://groovy.codehaus.org/Grape
Quick Start(快速开始)
Grape lets you quickly add maven repository dependencies to your classpath. Here are the most common solutions:
Grape让你快速的添加maven库依赖到classpath,下面是一些通用的解决方案:
Add a Dependency(添加一个依赖)
@Grab(group='org.springframework', module='spring', version='2.5.6')
import org.springframework.jdbc.core.JdbcTemplate
Yes, you can annotate an import in Groovy. You can also search for dependencies on mvnrepository.com and it will provide you the @Grab annotation form of the pom.xml entry.
是的,在Groovy中你可以注解一个import 。你也可以在 mvnrepository.com 搜索下依赖,它会为pom.xm提供@Grab注解的格式。
Specify Additional Repositories(指定额外的依赖库)
Not all dependencies are in maven central. You can add new ones like this:
并不是所有的依赖都在maven中心,你可以像这样添加依赖:
@GrabResolver(name='restlet', root='http://maven.restlet.org/')
@Grab(group='org.restlet', module='org.restlet', version='1.1.6')
Maven Classifiers(Maven 分级器)
Some maven dependencies need classifiers in order to be able to resolve. You can fix that like this:
一些依赖库需要添加classifiers以保证能够解析,可以这样来修正:
@Grab(group='net.sf.json-lib', module='json-lib', version='2.2.3', classifier='jdk15')
Excluding Transitive Dependencies(排除过渡性依赖)
Sometimes you will want to exclude transitive dependencies as you might be already using a slightly different but compatible version of some artifact. You can do this as follows:
有时你需要排除一些过渡性的依赖由于你可能已经用了一个稍微不一样的但可兼容的版本(的构件)。你可以像下面这样做:
@Grab('net.sourceforge.htmlunit:htmlunit:2.8')
@GrabExclude('xml-apis:xml-apis')
JDBC Drivers(JDBC驱动)
Because of the way JDBC drivers are loaded, you'll need to configure Grape to attach JDBC driver dependencies to the system class loader. I.e:
由于JDBC驱动类的加载方式,你需要配置一下Grape来添加JDBC驱动依赖附加到 system class loader。例如:
@GrabConfig(systemClassLoader=true)
@Grab(group='mysql', module='mysql-connector-java', version='5.1.6')
Using Grape From the Groovy Shell(在Groovy Shell中运用Grape)
From groovysh use the method call variant:
在groovysh中用方法调用
groovy.grape.Grape.grab([group:'org.springframework', module:'spring', version:'2.5.6'])
Proxy settings(代理设置)
If you are behind a firewall and/or need to use Groovy/Grape through a proxy server, you can specify those settings on the command like via the http.proxyHost and http.proxyPort system properties:
如果你使用了防火墙,或者需要通过一个代理服务器来用Groovy/Grape,那么你可以指定一些设置于命令行上,比如说通过 http.proxyHost和http.proxyPort等系统属性(system properties)。
groovy -Dhttp.proxyHost=yourproxy -Dhttp.proxyPort=8080 yourscript.groovy
Or you can make this system wide by adding these properties to your JAVA_OPTS environment variable:
或者你可以让它作用于整个系统范围,通过添加这些属性到你的JAVA_OPTS环境变量上:
JAVA_OPTS = -Dhttp.proxyHost=yourproxy -Dhttp.proxyPort=8080
Detail(细节)
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.
Groovy适配包装引擎或Groovy高级包装引擎是在Groovy中启用grab()调用的基础架构,是一套虑及Groovy库驱动模块系统的classes leveraging Ivy。它允许开发人员编写本质上需要任意库依赖的脚本。当脚本运行自已经存在的库时(如 Ibiblio, Codehaus, and java.net等),Grape会在运行时期按需下载并将已命名库与所有依赖连接成可传递的闭包。
Grape follows the Ivy conventions for module version identification, with naming change.
Grape遵循Ivy约定中的模块版本定义,with naming change(是包括naming change?还是说命名改变了)。
-
group
- Which module group the module comes from. Translates directly to a Maven groupId or an Ivy Organization. Any group matching/groovy[x][\..*]^/
is reserved and may have special meaning to the groovy endorsed modules. -
module
- The name of the module to load. Translated directly to a Maven artifactId or an Ivy artifact. -
version
- The version of the module to use. Either a literal version '1.1-RC3' or an Ivy Range '[2.2.1,)' meaning 2.2.1 or any greater version).
The downloaded modules will be stored according to Ivy's standard mechanism with a cache root of ~/.groovy/grape
下载的模块将会按照标准的机制保存在一个缓存目录:
~/.groovy/grape
Usage(用法)
Annotation(注解)
One or more groovy.lang.Grab annotations can be added at any place that annotations are accepted to tell the compiler that this code relies on the specific library. This will have the effect of adding the library to the classloader of the groovy compiler. This annotation is detected and evaluated before any other resolution of classes in the script, so imported classes can be properly resolved by a @Grab annotation.
一个或多个groovy.lang.Grab注解可以添加到注解可接收的地方来告诉编译器这些代码依赖于指定的库。这将起到给groovy编辑器的类加载器添加库的效果。此注解将会在代码中的其它类型解决方案之前被检测到并求值。因此引用类可以通过一个@Grab注解得到恰当的解决。
import com.jidesoft.swing.JideSplitButton
@Grab(group='com.jidesoft', module='jide-oss', version='[2.2.1,2.3.0)')
public class TestClassAnnotation {
public static String testMethod () {
return JideSplitButton.class.name
}
}
An appropriate grab(...)
call will be added to the static initializer of the class of the containing class (or script class in the case of an annotated script element).
一个适当的grab(...)调用当会添加到类初始化器。
Multiple Grape Annotations(多个Grap注解)
In order to use a Grape annotation multiple times you must use the Grapes annotation, e.g.:
要用多次Grape注解,你必须用Grapes注解,如:
@Grapes([
@Grab(group='commons-primitives', module='commons-primitives', version='1.0'),
@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7')])
class Example {
// ...
}
Otherwise you'll encounter the following error:
否则你将会遇到如下错误:
Cannot specify duplicate annotation on the same member
Typically a call to grab will occur early in the script or in class initialization. This is to insure that the libraries are made available to the ClassLoader before the groovy code relies on the code. A couple of typical calls may appear as follows:
往往一个grab的调用会发生在脚本或类初始化之前,这是为了保证在grooy代码依赖之前使得这些库对类加载器来说可用。下面是几个典型的调用:
import groovy.grape.Grape
// random maven library
Grape.grab(group:'com.jidesoft', module:'jide-oss', version:'[2.2.0,)')
Grape.grab([group:'org.apache.ivy', module:'ivy', version:'2.0.0-beta1', conf:['default', 'optional']],
[group:'org.apache.ant', module:'ant', version:'1.7.0'])
// endorsed Groovy Module
// FUTURE grab('Scriptom')
* Multiple calls to grab in the same context with the same parameters should be idempotent. However, if the same code is called with a different ClassLoader context then resolution may be re-run.
相同Context下,以相同参数多次对grab的调用应该是幂等的(结果相同)。然而,如果相同的代码被不同的 ClassLoader context 调用,那么解决方案可能会重新运行。
-
grab
is disabled by default. Starting callingGrape.initGrape()
will enable grab. Any calls to grab beforeinitGrape()
is called will be ignored. Hence Grape managed classloading is opt in only. Multiple calls tiGrape.initGrape()
after the first successful call are ignored. - If the
args
map passed into thegrab
call has an attributenoExceptions
that evaluates true no exceptions will be thrown. -
grab
requires that a RootLoader or GroovyClassLoader be specified or be in the ClassLoader chain of the calling class. By default failure to have such a ClassLoader available will result in module resolution and an exception being thrown (ifinitGrape()
has been called).- The ClassLoader passed in via the
classLoader:
argument and it's parent classloaders. - The ClassLoader of the object passed in as the
referenceObject:
argument, and it's parent classloaders. - The ClassLoader of the class issuing the call to
grab
- The ClassLoader passed in via the
grab(HashMap)
Parameters(参数)
-
group:
- <String> - Which module group the module comes from. Translates directly to a Maven groupId. Any group matching/groovy(
|x\..
)/
is reserved and may have special meaning to the groovy endorsed modules. -
module:
- <String> - The name of the module to load. Translated directly to a Maven artifactId. -
version:
- <String> and possibly <Range> - The version of the module to use. Either a literal version '1.1-RC3' or an Ivy Range '[2.2.1,)' meaning 2.2.1 or any greater version). -
classifier:
- <String> - The Maven classifier to resolve by. -
conf:
- <String>, default 'default' - The configuration or scope of the module to download. The default conf isdefault:
which maps to the mavenruntime
andmaster
scopes. -
force:
- <boolean>, defaults true - Used to indicate that this revision must be used in case of conflicts, independently of conflicts manager -
changing:
- <boolean>, default false - Whether the artifact can change without it's version designation changing. -
transitive:
- <boolean>, default true - Whether to resolve other dependencies this module has or not.
-
group:
- <String> - 模块所属组,将会直接翻译为Maven groupId.任何匹配/groovy(
|x\..
)/(正则表达式)
的组名将被保留,它可能对groovy授权的模块有特定意义。 -
module:
- <String> - 要加载模块的名称,将会被直接翻译为Maven artifactId。 -
version:
- <String> and possibly <Range> - 模块要用的版本,可以是一个文字版本号‘ 1.1-RC3 ’或一个Ivy版本范围‘ '[2.2.1,) ’(表示2.2.1或任意更高的版本)。 -
classifier:
- <String> - 指定 Maven classifier。 -
conf:
- <String>, default 'default' -模块下载的作用域配置。默认为default
映射到Maven的runtime
和master
作用域 . -
force:
- <boolean>, defaults true - 是否强制使用指定的版本,以防腐剂冲突或独立于冲突管理器之外。 -
changing:
- <boolean>, default false - 构件是否可以改变并不改变版本号 -
transitive:
- <boolean>, default true - 是否解决传递性依赖。
There are two principal variants of grab
, one with a single Map and one with an arguments Map and multiple dependencies map. A call to the single map grab is the same as calling grab with the same map passed in twice, so grab arguments and dependencies can be mixed in the same map, and grab can be called as a single method with named parameters.
grab有两个主要的变体,一个是带单个map,另一个是带一个参数map和多个依赖map。单map grab的调用相当于同一个map传递两次,因此grab的参数及依赖可以混合到一个map里,从而一个grab可以以一个带命名参数的方法来调用。
There are synonyms for these parameters. Submitting more than one is a runtime exception.
这些参数的名字是有同义词的,提交多个同义的参数将有产生运行时异常。
-
group:
,groupId:
,organisation:
,organization:
,org:
-
module:
,artifactId:
,artifact:
-
version:
,revision:
,rev:
-
conf:
,scope:
,configuration:
Arguments Map arguments
-
classLoader:
- <GroovyClassLaoder> or <RootClassLoader> - The ClassLoader to add resolved Jars to -
refObject:
- <Object> - The closest parent ClassLoader for the object's class will be treated as though it were passed in asclassLoader:
-
validate:
- <boolean>, default false - Should poms or ivy files be validated (true), or should we trust the cache (false). -
noExceptions:
- <boolean>, default false - If ClassLoader resolution or repository querying fails, should we throw an exception (false) or fail silently (true).
Command Line Tool(命令行工具)
Grape added a command line executable 'grape' that allows for the inspection and management of the local grape cache.
Grape添加了一个命令行执行程序‘grape’,可以用来查看和管理本地的grape缓存。
grape install <groupId> <artifactId> [<version>]
This installs the specified groovy module or maven artifact. If a version is specified that specific version will be installed, otherwise the most recent version will be used (as if '*' we passed in).
这将会安装一个指定的groovy模块或maven构件,如果指定了版本的话,将会安装指定的版本,否则会用最近的版本(我们传一个‘*’的话也同样)。
grape list
Lists locally installed modules (with their full maven name in the case of groovy modules) and versions.
列出本地已经安装的模块(如果是groovy模块的话将会带着它们的全maven名)及版本。
grape resolve (<groupId> <artifactId> <version>)+
This returns the file locations of the jars representing the artifcats for the specified module(s) and the respective transitive dependencies. You may optionally pass in -ant, -dos, or -shell to get the dependencies expressed in a format applicable for an ant script, windows batch file, or unix shell script respectively. -ivy may be passed to see the dependencies expressed in an ivy like format.
这将列返回指定模块的构件路径及其传递性依赖,你可以任意的传递-ant,-dos,或-shell来分别得到该依赖的ant脚本,windows批处理文件,或unix shell脚本。传递-ivy可以看到该依赖的类ivy格式。
Advanced configuration(高级配置)
Repository Directory(库目录)
If you need to change the directory grape uses for downloading libraries you can specify the grape.root system property to change the default (which is ~/.groovy/grape)
如果需要改变grape的库下载目录,你可以指定grape.root系统属性来改变默认值(默认值为‘~/.groovy/grape’)
groovy -Dgrape.root=/repo/grape yourscript.groovy
Customize Ivy settings(自定义Ivy设置)
//TODO expand on discussion of grapeConfig.xml
You can customize the ivy settings that Grape uses by creating a ~/.groovy/grapeConfig.xml file. If no such file exists,here are the default settings used by Grape:
你可以通过创建一个~/.groovy/grapeConfig.xml文件来自定义ivy的设置。如果此文件不存在,Grape将会默认用这个设置。
<ivysettings>
<settings defaultResolver="downloadGrapes"/>
<resolvers>
<chain name="downloadGrapes">
<filesystem name="cachedGrapes">
<ivy pattern="${user.home}/.groovy/grapes/[organisation]/[module]/ivy-[revision].xml"/>
<artifact pattern="${user.home}/.groovy/grapes/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/>
</filesystem>
<!-- todo add 'endorsed groovy extensions' resolver here -->
<ibiblio name="codehaus" root="http://repository.codehaus.org/" m2compatible="true"/>
<ibiblio name="ibiblio" m2compatible="true"/>
<ibiblio name="java.net2" root="http://download.java.net/maven/2/" m2compatible="true"/>
</chain>
</resolvers>
</ivysettings>
For more information on how to customize these settings, please refer to the Ivy documentation.
关于如何自定义配置的更多信息,请参考:Ivy文档
Add your local Maven2 repository(添加本地Maven库)
If you find yourself wanting to reuse artifacts that you already have locally in your Maven2 repository, then you can add this line to your ~/.groovy/grapeConfig.xml:
如果想要重用你的Maven2本地仓库中的构件的话,你可以将这行内容添加到你的 ~/.groovy/grapeConfig.xml中:
<ibiblio name="local" root="file:${user.home}/.m2/repository/" m2compatible="true"/>
And further customize your Grape configuration:
<?xml version="1.0"?>
<ivysettings>
<settings defaultResolver="downloadGrapes"/>
<resolvers>
<chain name="downloadGrapes">
<!-- todo add 'endorsed groovy extensions' resolver here -->
<ibiblio name="local" root="file:${user.home}/.m2/repository/" m2compatible="true"/>
<filesystem name="cachedGrapes">
<ivy pattern="${user.home}/.groovy/grapes/[organisation]/[module]/ivy-[revision].xml"/>
<artifact pattern="${user.home}/.groovy/grapes/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/>
</filesystem>
<ibiblio name="codehaus" root="http://repository.codehaus.org/" m2compatible="true"/>
<ibiblio name="ibiblio" m2compatible="true"/>
<ibiblio name="java.net2" root="http://download.java.net/maven/2/" m2compatible="true"/>
</chain>
</resolvers>
</ivysettings>
More Examples(更多示例)
Using Apache Commons Collections:
// create and use a primitive array
import org.apache.commons.collections.primitives.ArrayIntList
@Grab(group='commons-primitives', module='commons-primitives', version='1.0')
def createEmptyInts() { new ArrayIntList() }
def ints = createEmptyInts()
ints.add(0, 42)
assert ints.size() == 1
assert ints.get(0) == 42
Using TagSoup:
// find the PDF links in the Java 1.5.0 documentation
@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7')
def getHtml() {
def parser = new XmlParser(new org.ccil.cowan.tagsoup.Parser())
parser.parse("http://java.sun.com/j2se/1.5.0/download-pdf.html")
}
html.body.'**'.a.@href.grep(~/.*\.pdf/).each{ println it }
Using Google Collections:
// Google Collections example
import com.google.common.collect.HashBiMap
@Grab(group='com.google.code.google-collections', module='google-collect', version='snapshot-20080530')
def getFruit() { [grape:'purple', lemon:'yellow', orange:'orange'] as HashBiMap }
assert fruit.lemon == 'yellow'
assert fruit.inverse().yellow == 'lemon'
Launching a Jetty server to server Groovy templates:
import org.mortbay.jetty.Server
import org.mortbay.jetty.servlet.*
import groovy.servlet.*
@Grab(group = 'org.mortbay.jetty', module = 'jetty-embedded', version = '6.1.0')
def runServer(duration) {
def server = new Server(8080)
def context = new Context(server, "/", Context.SESSIONS);
context.resourceBase = "."
context.addServlet(TemplateServlet, "*.gsp")
server.start()
sleep duration
server.stop()
}
runServer(10000)
Grape will download Jetty and its dependencies on first launch of this script, and cache them. We're creating a new Jetty Server on port 8080, then expose Groovy's TemplateServlet at the root of the context — Groovy comes with its own powerful template engine mechanism. We start the server and let it run for a certain duration. Each time someone will hithttp://localhost:8080/somepage.gsp, it will display the somepage.gsp template to the user — those template pages should be situated in the same directory as this server script.
Grape将会在第一次启动本脚本时下载Jetty及其依赖,并缓存之。我们会在端口8080创建一个Jetty服务,然后开放context根下的Grooy的TemplateServlet(Grooy自带的一个强大的模板引擎机制)。我们启动服务并保持其运行一段特定的时间,每当有人访问http://localhost:8080/somepage.gsp,它将为用户显示somepage.gsp模板(这些模板文件将和此服务脚本位于相同的目录)。