官术网_书友最值得收藏!

  • 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:

  1. For example, the search.groovy script is dependent on Apache Commons 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
  2. 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

主站蜘蛛池模板: 秭归县| 静海县| 安西县| 陆河县| 专栏| 南宫市| 女性| 南城县| 澄迈县| 新丰县| 三门峡市| 营山县| 抚州市| 江油市| 连云港市| 南开区| 德保县| 磴口县| 宜州市| 江川县| 诏安县| 保山市| 宣城市| 伽师县| 闻喜县| 通州区| 沽源县| 长海县| 台安县| 怀安县| 天峻县| 元江| 中超| 韩城市| 隆昌县| 宝山区| 临漳县| 正阳县| 龙江县| 维西| 观塘区|