| ////////////////////////////////////////// |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| |
| ////////////////////////////////////////// |
| ifndef::tools-groovy[] |
| :tools-groovy: tools-groovy.adoc |
| endif::[] |
| |
| [[section-grape]] |
| = Dependency management with Grape |
| |
| == Quick start |
| |
| === Add a Dependency |
| |
| Grape is a JAR dependency manager embedded into Groovy. Grape lets you quickly add maven repository dependencies to your |
| classpath, making scripting even easier. The simplest use is as simple as adding an annotation to your script: |
| |
| [source,groovy] |
| -------------------------------------------------------------------- |
| @Grab(group='org.springframework', module='spring-orm', version='5.2.8.RELEASE') |
| import org.springframework.jdbc.core.JdbcTemplate |
| -------------------------------------------------------------------- |
| |
| `@Grab` also supports a shorthand notation: |
| |
| [source,groovy] |
| -------------------------------------------------------------------- |
| @Grab('org.springframework:spring-orm:5.2.8.RELEASE') |
| import org.springframework.jdbc.core.JdbcTemplate |
| -------------------------------------------------------------------- |
| |
| Note that we are using an annotated import here, which is the recommended way. You can also search for |
| dependencies on http://mvnrepository.com[mvnrepository.com] and it will |
| provide you the `@Grab` annotation form of the `pom.xml` entry. |
| |
| [[Grape-SpecifyAdditionalRepositories]] |
| === Specify Additional Repositories |
| |
| Not all dependencies are in maven central. You can add new ones like |
| this: |
| |
| [source,groovy] |
| ----------------------------------------------------------------- |
| @GrabResolver(name='restlet', root='http://maven.restlet.org/') |
| @Grab(group='org.restlet', module='org.restlet', version='1.1.6') |
| ----------------------------------------------------------------- |
| |
| [[Grape-MavenClassifiers]] |
| === Maven Classifiers |
| |
| Some maven dependencies need classifiers in order to be able to resolve. |
| You can fix that like this: |
| |
| [source,groovy] |
| -------------------------------------------------------------------------------------- |
| @Grab(group='net.sf.json-lib', module='json-lib', version='2.2.3', classifier='jdk15') |
| -------------------------------------------------------------------------------------- |
| |
| [[Grape-ExcludingTransitiveDependencies]] |
| === 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: |
| |
| [source,groovy] |
| ---------------------------------------------- |
| @Grab('net.sourceforge.htmlunit:htmlunit:2.8') |
| @GrabExclude('xml-apis:xml-apis') |
| ---------------------------------------------- |
| |
| [[Grape-JDBCDrivers]] |
| === JDBC Drivers |
| |
| 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: |
| |
| [source,groovy] |
| -------------------------------------------------------------------- |
| @GrabConfig(systemClassLoader=true) |
| @Grab(group='mysql', module='mysql-connector-java', version='5.1.6') |
| -------------------------------------------------------------------- |
| |
| [[Grape-UsingGrapeFromtheGroovyShell]] |
| === Using Grape From the Groovy Shell |
| |
| From groovysh use the method call variant: |
| |
| [source,groovy] |
| ---------------------------------------------------------------------------------------- |
| groovy.grape.Grape.grab(group:'org.springframework', module:'spring', version:'2.5.6') |
| ---------------------------------------------------------------------------------------- |
| |
| [[Grape-Proxysettings]] |
| === 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 -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 = -Dhttp.proxyHost=yourproxy -Dhttp.proxyPort=8080 |
| ------------------------------------------------------------ |
| |
| [[Grape-Logging]] |
| === Logging |
| |
| The Grape facade (`groovy.grape.Grape`) uses |
| https://docs.oracle.com/en/java/javase/17/docs/api/java.logging/java/lang/System.Logger.html[JDK Platform Logging] |
| and can be configured through `~/.groovy/logging.properties` |
| (see <<{tools-groovy}#section-groovy-commandline,the groovy command>> for details). |
| |
| Logging of the underlying engine depends on which Grape implementation is active. |
| |
| ==== GrapeIvy logging |
| |
| GrapeIvy routes Ivy's internal logging through JDK Platform Logging |
| under the logger name `groovy.grape.ivy`. To control the verbosity, |
| set the level in `~/.groovy/logging.properties`: |
| |
| [source,properties] |
| ---- |
| # Show Ivy info messages (INFO, WARNING, ERROR) |
| groovy.grape.ivy.level=INFO |
| |
| # Show verbose Ivy output (adds dependency resolution details) |
| groovy.grape.ivy.level=FINE |
| |
| # Show all Ivy debug output |
| groovy.grape.ivy.level=FINEST |
| ---- |
| |
| The `grape` command's `-q`, `-w`, `-i`, `-V`, and `-d` flags also |
| adjust the Ivy logging level for that invocation. |
| |
| If you want to see download progress specifically, set the system property |
| `groovy.grape.report.downloads` to `true` (e.g. add |
| `-Dgroovy.grape.report.downloads=true` to invocation or JAVA_OPTS) and Grape will |
| print the following infos to System.error: |
| |
| * Starting resolve of a dependency |
| * Starting download of an artifact |
| * Retrying download of an artifact |
| * Download size and time for downloaded artifacts |
| |
| ==== GrapeMaven logging |
| |
| When using the GrapeMaven engine, set `-Dgroovy.grape.debug=true` to |
| enable verbose Maven Resolver logging to `System.err`. The |
| `groovy.grape.report.downloads` property has no effect with this engine. |
| |
| [[Grape-Detail]] |
| == Detail |
| |
| Grape (The _Groovy Adaptable Packaging Engine_ or _Groovy Advanced |
| Packaging Engine_) is the infrastructure enabling the grab() calls in |
| Groovy, a repository-driven module system that 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 |
| Maven Central. |
| |
| Groovy ships with two Grape engine implementations: `GrapeIvy`, based on |
| http://ant.apache.org/ivy/[Apache Ivy], and `GrapeMaven`, based on |
| https://maven.apache.org/resolver/[Maven Resolver (Aether)]. They |
| provide the same core `@Grab` / `@GrabResolver` / `@GrabExclude` |
| experience but differ in some areas of advanced configuration and |
| behaviour; see <<Grape-Implementations>> for details. |
| |
| Grape follows the Ivy conventions for module version identification, |
| with 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 a range `[2.2.1,)' meaning 2.2.1 or any greater version). |
| * `classifier` - The optional classifier to use (for example, _jdk15_) |
| |
| The downloaded modules will be stored according to the active engine's |
| cache conventions (see <<Grape-Implementations>> for per-engine cache |
| directories). |
| |
| [[Grape-Implementations]] |
| === Grape Implementations |
| |
| Groovy ships with two built-in Grape engine implementations. Both support |
| the same core `@Grab`, `@GrabResolver`, and `@GrabExclude` annotations and |
| method calls. They differ in their underlying resolution mechanism, cache |
| layout, and some advanced configuration options. |
| |
| ==== Built-in implementations |
| |
| ===== GrapeIvy (default) |
| |
| `groovy.grape.ivy.GrapeIvy` uses http://ant.apache.org/ivy/[Apache Ivy] |
| for dependency resolution. It is the default engine when both implementations |
| are on the classpath. |
| |
| * *Backend*: Apache Ivy |
| * *Local cache*: `~/.groovy/grapes` (Ivy's standard cache format) |
| * *Configuration file*: `~/.groovy/grapeConfig.xml` (full Ivy XML settings — see <<Grape-CustomizeIvysettings>>) |
| * *`@GrabConfig(autoDownload=false)`*: Supported. When `false`, resolution |
| is restricted to the local cache; no network calls are made. |
| * *`conf:` parameter*: Mapped directly to Ivy configurations; multiple |
| configurations such as `conf:['default','optional']` are supported. |
| * *Version wildcards*: `'*'` resolves to Ivy's `latest.default`. |
| |
| ===== GrapeMaven |
| |
| `groovy.grape.maven.GrapeMaven` uses |
| https://maven.apache.org/resolver/[Maven Resolver (Aether)] |
| for dependency resolution. |
| |
| * *Backend*: Maven Resolver (Aether) |
| * *Local cache*: `~/.groovy/grapesM2` (Maven local-repository format) |
| * *Configuration*: Remote repositories configured via `@GrabResolver` or |
| the `Grape.addResolver()` API; no configuration file equivalent. |
| * *`@GrabConfig(autoDownload=…)`*: The `autoDownload` flag is not |
| honoured; GrapeMaven always attempts remote resolution when an artifact |
| is not already cached. |
| * *`conf:` parameter*: Treated as a Maven scope; `'default'` is mapped |
| to `'compile'`. Multiple configurations in a single grab are not supported. |
| * *Version wildcards*: `'*'` resolves to Maven's `LATEST`. |
| |
| ==== Selecting an implementation |
| |
| When both `groovy-grape-ivy` and `groovy-grape-maven` are on the |
| classpath, `GrapeIvy` is preferred by default. To switch to GrapeMaven |
| for a script, pass the system property: |
| |
| ------------------------------------------------------------------------- |
| groovy -Dgroovy.grape.impl=groovy.grape.maven.GrapeMaven yourscript.groovy |
| ------------------------------------------------------------------------- |
| |
| Or set it globally via `JAVA_OPTS`: |
| |
| ------------------------------------------------------------------------- |
| JAVA_OPTS=-Dgroovy.grape.impl=groovy.grape.maven.GrapeMaven |
| ------------------------------------------------------------------------- |
| |
| ==== Migration considerations |
| |
| Most existing `@Grab` scripts work unchanged with both engines, but |
| there are some compatibility notes to consider: |
| |
| * *`conf:` parameter*: GrapeIvy supports multiple Ivy configurations |
| (e.g., `conf:['default','optional']`), while GrapeMaven treats `conf:` |
| as a singular Maven scope (e.g., `conf:'compile'`). Scripts using |
| multiple configurations must remain on GrapeIvy or be reworked. |
| |
| * *Custom Ivy configuration*: If you have customized |
| `~/.groovy/grapeConfig.xml` with non-standard Ivy settings (especially |
| if you disabled the default `m2compatible=true`), those settings do not |
| apply to GrapeMaven. Review your configuration before switching, or |
| reconfigure custom repositories using `@GrabResolver` annotations. |
| |
| * *`@GrabConfig(autoDownload=false)`*: GrapeMaven does not honour |
| `autoDownload=false` as a per-grab switch. The closest equivalent is |
| to point `@GrabResolver` (or `Grape.addResolver`) to a local-only |
| repository/cache location. If you rely on `autoDownload=false` |
| semantics broadly, remain on GrapeIvy. |
| |
| ==== Custom implementations |
| |
| You can provide your own `GrapeEngine` implementation by including a jar |
| on the classpath that declares it as a Java SPI (Service Provider Interface). |
| Groovy will discover and load it via `java.util.ServiceLoader`. |
| |
| To register a custom implementation: |
| |
| 1. Create a class implementing `groovy.grape.GrapeEngine`. |
| 2. Add a service provider configuration file at |
| `META-INF/services/groovy.grape.GrapeEngine` in your jar with a single |
| line naming the fully-qualified class name. |
| 3. Place the jar on the classpath. |
| |
| You can then select it with: |
| |
| ------------------------------------------------------------------------- |
| groovy -Dgroovy.grape.impl=my.custom.GrapeImpl yourscript.groovy |
| ------------------------------------------------------------------------- |
| |
| If your implementation is the only one on the classpath, it will be |
| automatically discovered and used by default. If multiple implementations |
| are present (including the built-ins), you must specify which one to use |
| via the system property. |
| |
| [[Grape-Usage]] |
| == Usage |
| |
| [[Grape-Annotation]] |
| === 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. |
| |
| Supported annotation targets include imports (recommended), classes, |
| methods, constructors, fields, parameters, and local variables. |
| |
| Here is an example placing `@Grab` on a class: |
| |
| [source,groovy] |
| ----------------------------------------------------------------------- |
| 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 |
| } |
| } |
| ----------------------------------------------------------------------- |
| |
| Here is an example placing `@Grab` on a local variable: |
| |
| [source,groovy] |
| ----------------------------------------------------------------------- |
| @Grab('commons-lang:commons-lang:2.4') |
| var input = 'hello world' |
| println org.apache.commons.lang.WordUtils.capitalize(input) |
| ----------------------------------------------------------------------- |
| |
| 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). |
| |
| [[Grape-MultipleGrapeAnnotations]] |
| === Multiple Grape Annotations |
| |
| In early versions of Groovy, if you wanted to use a Grab annotation multiple times |
| on the same node you had to use the `@Grapes` annotation, e.g.: |
| |
| [source,groovy] |
| --------------------------------------------------------------------------------- |
| @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’d encounter the following error: |
| |
| ------------------------------------------------------ |
| Cannot specify duplicate annotation on the same member |
| ------------------------------------------------------ |
| |
| But in recent versions, @Grapes is purely optional. |
| |
| Technical notes: |
| |
| * Originally, Groovy stored the Grab annotations for access at runtime |
| and duplicates aren't allowed in the bytecode. In current versions, @Grab has only |
| SOURCE retention, so the multiple occurrences aren't an issue. |
| * Future versions of Grape may support using the Grapes annotation to |
| provide a level of structuring, e.g. allowing a GrabExclude or GrabResolver |
| annotation to apply to only a subset of the Grab annotations. |
| |
| [[Grape-Methodcall]] |
| === Method call |
| |
| Typically a call to grab will occur early in the script or in class |
| initialization. This is to ensure 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: |
| |
| [source,groovy] |
| ------------------------------------------------------------------------------------------------------- |
| 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']) |
| ------------------------------------------------------------------------------------------------------- |
| |
| * 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. |
| * 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 |
| ** The ClassLoader passed in via the `classLoader:` argument and its |
| parent classloaders. |
| ** The ClassLoader of the object passed in as the `referenceObject:` |
| argument, and its parent classloaders. |
| ** The ClassLoader of the class issuing the call to `grab` |
| |
| [[Grape-grabHashMapParameters]] |
| ==== grab(HashMap) Parameters |
| |
| * `group:` - <String> - Which module group the module comes from. |
| Translates directly to a Maven groupId. Any group matching |
| `/groovy(|\..|x|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 is `default:` 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 its version designation changing. |
| * `transitive:` - <boolean>, default true - Whether to resolve other |
| dependencies this module has or not. |
| |
| 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. |
| |
| 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:` |
| |
| [[Grape-ArgumentsMaparguments]] |
| ==== Arguments Map arguments |
| |
| * `classLoader:` - <GroovyClassLoader> 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). |
| |
| [[Grape-CommandLineTool]] |
| === Command Line Tool |
| |
| Grape added a command line executable `grape' that allows for the |
| inspection and management of the local grape cache. |
| |
| ------------------------------------------------ |
| grape install [-hv] <group> <module> [<version>] [<classifier>] |
| ------------------------------------------------ |
| |
| 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). |
| |
| ---------- |
| grape list |
| ---------- |
| |
| Lists locally installed modules (with their full maven name in the case |
| of groovy modules) and versions. |
| |
| ------------------------------------------------- |
| grape resolve [-adhisv] (<groupId> <artifactId> <version>)+ |
| ------------------------------------------------- |
| |
| This returns the file locations of the jars representing the artifacts |
| 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. |
| |
| ------------------------------------------------- |
| grape uninstall [-hv] <group> <module> <version> |
| ------------------------------------------------- |
| |
| This uninstalls a particular grape: it non-transitively removes the |
| respective jar file from the grape cache. |
| |
| [[Grape-Advancedconfiguration]] |
| === Advanced configuration |
| |
| [[Grape-RepositoryDirectory]] |
| ==== Repository Directory |
| |
| The local cache directory used by each engine is: |
| |
| * *GrapeIvy*: `~/.groovy/grapes` |
| * *GrapeMaven*: `~/.groovy/grapesM2` |
| |
| If you need to change the root directory that Grape uses for downloading |
| libraries you can specify the `grape.root` system property to change the |
| default (which is `~/.groovy`). Both engines respect this property. |
| |
| ------------------------------------------------- |
| groovy -Dgrape.root=/repo/grapes yourscript.groovy |
| ------------------------------------------------- |
| |
| [[Grape-CustomizeIvysettings]] |
| ==== Customize Ivy settings (GrapeIvy only) |
| |
| When using GrapeIvy, you can customize the Ivy settings that Grape uses by creating a |
| `~/.groovy/grapeConfig.xml` file. If no such file exists, |
| https://github.com/apache/groovy/blob/master/src/resources/groovy/grape/defaultGrapeConfig.xml[here] |
| are the default settings used by Grape. |
| |
| For more information on how to customize these settings, please refer to |
| the https://ant.apache.org/ivy/history/latest-milestone/index.html[Ivy |
| documentation]. |
| |
| This configuration file is not used by the GrapeMaven engine; with |
| GrapeMaven, additional remote repositories are registered via |
| `@GrabResolver` annotations or programmatically via the |
| `Grape.addResolver` API. |
| |
| [[Grape-MoreExamples]] |
| === More Examples |
| |
| Using Apache Commons Collections: |
| |
| [source,groovy] |
| ----------------------------------------------------------------------------- |
| // create and use a primitive array list |
| @Grab(group='commons-primitives', module='commons-primitives', version='1.0') |
| import org.apache.commons.collections.primitives.ArrayIntList |
| |
| def createEmptyInts() { new ArrayIntList() } |
| |
| def ints = createEmptyInts() |
| ints.add(0, 42) |
| assert ints.size() == 1 |
| assert ints.get(0) == 42 |
| ----------------------------------------------------------------------------- |
| |
| Using TagSoup: |
| |
| [source,groovy] |
| ------------------------------------------------------------------------ |
| // find the PDF links of the Java specifications |
| @Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='1.2.1') |
| def getHtml() { |
| def parser = new XmlParser(new org.ccil.cowan.tagsoup.Parser()) |
| parser.parse("https://docs.oracle.com/javase/specs/") |
| } |
| html.body.'**'.a.@href.grep(~/.*\.pdf/).each{ println it } |
| ------------------------------------------------------------------------ |
| |
| Using Google Collections: |
| |
| [source,groovy] |
| ------------------------------------------------------------------------------------------------------- |
| 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 serve Groovy templates: |
| |
| [source,groovy] |
| -------------------------------------------------------------------------------------------------- |
| @Grab('org.eclipse.jetty.aggregate:jetty-server:8.1.19.v20160209') |
| @Grab('org.eclipse.jetty.aggregate:jetty-servlet:8.1.19.v20160209') |
| @Grab('javax.servlet:javax.servlet-api:3.0.1') |
| import org.eclipse.jetty.server.Server |
| import org.eclipse.jetty.servlet.ServletContextHandler |
| import groovy.servlet.TemplateServlet |
| |
| def runServer(duration) { |
| def server = new Server(8080) |
| def context = new ServletContextHandler(server, "/", ServletContextHandler.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 create 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 hit |
| +http://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. |
| |