- Groovy 2 Cookbook
- Andrey Adamovich Luciano Fiandesio
- 693字
- 2021-07-23 15:57:23
Simplifying dependency management with Grape
Your nicely written and useful script can solve many interesting problems with the help of third-party libraries, and as long as it resides on your machine and has all the dependencies in place, it will work perfectly. However, at the point when you need to share it with your colleagues or community, you will realize that small and concise code requires several megabytes of additional libraries to be passed together with the script in order to make it work. Luckily, Groovy has a solution for that called Grape.
In this recipe, we will show you how to declare and automatically load Groovy script dependencies with the help of the wonderful Grape tool, which is integrated into Groovy.
Getting ready
Grape stands for the Groovy Adaptable (Advanced) Packaging Engine, and it is a part of the Groovy installation. Grape helps you download and cache external dependencies from within your script with a set of simple annotations.
How to do it...
If, in your script, you require an external dependency, that you know is available in a public repository as Maven Central Repository, you can use @Grab
annotation to annotate your import
, class
, or method
with a reference to that library, and Groovy will automatically download it, cache it, and put it on the class path of your script:
- For example, the
search.groovy
script is dependent on ApacheCommons HttpClient
library for making a Google search and saving a result page to a local file:@Grab('org.apache.httpcomponents:httpclient:4.2.1') import org.apache.http.impl.client.DefaultHttpClient import org.apache.http.client.methods.HttpGet def httpClient = new DefaultHttpClient() def url = 'http://www.google.com/search?q=Groovy' def httpGet = new HttpGet(url) def httpResponse = httpClient.execute(httpGet) new File('result.html').text =httpResponse.entity.content.text
- To execute the script, just use the usual invocation:
groovy search.groovy
mechanism. Groovy will automatically detect any external dependency requirements and tell Grape to fetch it before script execution.
How it works...
The first time the script gets executed, we experience a delay while the dependencies are downloaded. The second time, the script will execute faster because all libraries will be cached in Grape's cache directory, located in .groovy\grapes
, in the user's home
folder. Groovy also provides a command-line tool, grape
, to overview and control Grape's library cache. If the Grape's cache was empty in the beginning, then after our script execution, grape's list command will output something as follows:
commons-codec commons-codec [1.6] commons-logging commons-logging [1.1.1] org.apache apache [4, 9] org.apache.commons commons-parent [22, 5] org.apache.httpcomponents httpclient [4.2.1] org.apache.httpcomponents httpcomponents-client [4.2.1] org.apache.httpcomponents httpcomponents-core [4.2.1] org.apache.httpcomponents httpcore [4.2.1] org.apache.httpcomponents project [6] org.ccil.cowan.tagsoup tagsoup [1.2] 10 Grape modules cached 12 Grape module versions cached
You can put @Grab
annotation preceding various elements of the code.
On import
:
@Grab('org.apache.httpcomponents:httpclient:4.2.1') import org.apache.http.impl.client.DefaultHttpClient def httpClient = new DefaultHttpClient()
On variable:
@Grab('org.apache.httpcomponents:httpclient:4.2.1') def httpClient =new org.apache.http.impl.client.DefaultHttpClient()
On method:
@Grab('org.apache.httpcomponents:httpclient:4.2.1') def getHttpClient() { new org.apache.http.impl.client.DefaultHttpClient() }
On class
:
@Grab('org.apache.httpcomponents:httpclient:4.2.1') class Searcher { def httpClient Searcher() { httpClient = new org.apache.http.impl.client.DefaultHttpClient() } }
The only rule is that @Grab
should appear before the first usage of the imported class; otherwise the Groovy compiler will complain about it.
There's more...
Additionally, the @Grapes
annotation can be used to group several dependencies as follows:
@Grapes([ @Grab('org.apache.httpcomponents:httpclient:4.2.1'), @Grab('org.ccil.cowan.tagsoup:tagsoup:1.2')]) class Searcher { ... }
By default, Grape is using the Maven Central Repository (located at http://search.maven.org/) for downloading libraries. If you need to add your own repository, then you can either change grapeConfig.xml
, which is in fact, an Apache Ivy configuration, or you can use the @GrabResolver
annotation inside the script itself to make it more portable:
@GrabResolver(name='codehaus', root='http://repository.codehaus.org/') class Searcher { ... }
Like with any dependency management tool, sometimes you need to exclude certain dependencies from a dependency tree, and there, the @GrabExclude
annotation comes to the rescue:
@GrabExclude(group='commons-codec',module='commons-codec') class Searcher { ... }
Under the hood, Grape is using the Apache Ivy library for dependency management and resolution.
If you don't want to wait for the artifact download upon script start, you can use the grape install
command to install artifacts before execution:
grape install org.apache.httpcomponents httpclient 4.2.1
You can also use the Grape API directly and prefetch the required dependencies using another Groovy script:
import groovy.grape.Grape Grape.grab(group: 'org.apache.httpcomponents',module: 'httpclient',version: '4.2.1')
See also
- Grape documentation: http://groovy.codehaus.org/Grape
- Apache Ivy: https://ant.apache.org/ivy/
- Clojure Programming Cookbook
- JavaScript高效圖形編程
- C語言程序設計(第2 版)
- Python語言程序設計
- 編寫高質量代碼:改善C程序代碼的125個建議
- Learning Neo4j 3.x(Second Edition)
- Modular Programming in Java 9
- 網站構建技術
- Unity UI Cookbook
- Raspberry Pi Home Automation with Arduino(Second Edition)
- 單片機C語言程序設計實訓100例
- Hadoop 2.X HDFS源碼剖析
- Android Game Programming by Example
- WebStorm Essentials
- Instant AutoIt Scripting