Skip to content
Skip to breadcrumbs
Skip to header menu
Skip to action menu
Skip to quick search
Quick Search
Browse
Pages
Blog
Labels
Attachments
Mail
Advanced
What’s New
Space Directory
Feed Builder
Keyboard Shortcuts
Confluence Gadgets
Log In
Sign Up
Dashboard
Groovy
Copy Page
You are not logged in. Any changes you make will be marked as
anonymous
. You may want to
Log In
if you already have an account. You can also
Sign Up
for a new account.
This page is being edited by
.
Paragraph
Paragraph
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Preformatted
Quote
Bold
Italic
Underline
More colours
Strikethrough
Subscript
Superscript
Monospace
Clear Formatting
Bullet list
Numbered list
Outdent
Indent
Align left
Align center
Align right
Link
Table
Insert
Insert Content
Image
Link
Attachment
Symbol
Emoticon
Wiki Markup
Horizontal rule
tinymce.confluence.insert_menu.macro_desc
Info
JIRA Issue
Status
Gallery
Tasklist
Table of Contents
Other Macros
Page Layout
No Layout
Two column (simple)
Two column (simple, left sidebar)
Two column (simple, right sidebar)
Three column (simple)
Two column
Two column (left sidebar)
Two column (right sidebar)
Three column
Three column (left and right sidebars)
Undo
Redo
Find/Replace
Keyboard Shortcuts Help
<h1>Abstract</h1> <p>Grape (The Groovy Adaptable Packaging Engine or Groovy Advanced Packaging Engine) is the infrastructure enabling the <code>grab()</code> calls in Groovy, a set of classes leveraging <a href="http://ant.apache.org/ivy">Ivy</a> 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.</p> <h1>TimeFrame</h1> <p>The prototype is ready for inclusion into the trunk immediately, however the principal dependent library used (<a href="http://ant.apache.org/ivy/">Apache Ivy</a>) is a SVN snapshot. We should at least wait for a Beta 2 release and preferably for an RC release of the library before merging into trunk. That makes it a possible 1.6 candidate, and more likely a 1.7 candidate.</p> <h1>General Requirements</h1> <ul> <li>There must be a means to cause all calls to the Grape system to become no-ops and rely strictly on the JVM classpath.</li> <li>Grape should support bringing in packages from Maven 2 repositories.</li> <li>There should be some notion of 'endorsed modules' that are shortcutted in for easier use. For example: Scriptom, GroovyWS, SwingXBuilder. These can be hosted as regular Maven2 POMS or some other repository mechanism can be used.</li> <li>There should be command line tools similar to RubyGems, to add, remove, enumerate, and update versions of Grapes stored in the local cache.</li> <li>The implementation should not prevent movement into a container style module system such as integrating OSGi or Java 7 Super Packages. (this requirement should not be construed as an endorsement of either)</li> </ul> <h1>Specification</h1> <h2>Module versioning model.</h2> <p>Grape follows the Ivy conventions for module version identificaiton, with naming change.</p> <ul> <li><code>group</code> - Which module group the module comes from. Translates directly to a Maven groupId or an Ivy Organization. Any group matching <code>/groovy[x][\..*]^/</code> is reserved and may have special meaning to the groovy endorsed modules.</li> <li><code>module</code> - The name of the module to load. Translated directly to a Maven artifactId or an Ivy artifact.</li> <li><code>version</code> - 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).</li> </ul> <h2>Code Level Support</h2> <h3>Annotation</h3> <p>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.</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>import com.jidesoft.swing.JideSplitButton @Grab(group='com.jidesoft', module='jide-oss', version='[2.2.1,)') public class TestClassAnnotation { public static String testMethod () { return JideSplitButton.class.name } } </pre></td></tr></table> <p>An appropriate <code>grab(...)</code> 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).</p> <blockquote><p>TODO: How do we add a grab annotation to straight scripts? The current workaround is to annotate something in the script that can accept an annotation, like a method or parameter.</p></blockquote> <h3>Method call</h3> <p>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:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>// random maven library groovy.grape.Grape.grab(group:'com.jidesoft', module:'jide-oss', version:'[2.2.0,)') groovy.grape.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') </pre></td></tr></table> <p>* <code><span style="text-decoration: line-through;">grab(Object self, String module)</span></code>,- <code>grab(Object self, Map attrs)</code>, and <code>grab(Object self, Map attrs, Map... dependencies)</code> will be added to the DGM so that references to the backing Grape classes will not be needed. These will be proxies to the main Grape class calls.</p> <ul> <li>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.</li> <li><code>grab</code> is disabled by default. Starting calling <code>Grape.initGrape()</code> will enable grab. Any calls to grab before <code>initGrape()</code> is called will be ignored. Hence Grape managed classloading is opt in only.</li> <li>If the <code>args</code> map passed into the <code>grab</code> call has an attribute <code>noExceptions</code> that evaluates true no exceptions will be thrown.</li> <li><code>grab</code> 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 <code>initGrape()</code> has been called). <ul> <li>The ClassLoader passed in via the <code>classLoader:</code> argument and it's parent classloaders.</li> <li>The ClassLoader of the object passed in as the <code>referenceObject:</code> argument, and it's parent classloaders.</li> <li>The ClassLoader of the class issuing the call to <code>grab</code></li> </ul> </li> <li><code><span style="text-decoration: line-through;">grab(String)</span></code> <span style="text-decoration: line-through;">is a shortcut for endorsed groovy modules and will be equivilant to</span> <code><span style="text-decoration: line-through;">grab(group:'groovy.endorsed', module:<the module>, version:<the version of groovy being run>)</span></code><blockquote><p>TODO: all discussion of grab(String} are purely hypothetical as it hasn't been prototyped or the needed infrastructure set up</p></blockquote></li> </ul> <h4><code>grab(HashMap)</code> Parameters</h4> <ul> <li><code>group:</code> - <String> - Which module group the module comes from. Translates directly to a Maven groupId. Any group matching <code>/groovy(</code><code><sup>|\..</sup></code><code><strong><sup>|x</sup></strong></code><code><strong>|x\..</strong></code><code>)/</code> is reserved and may have special meaning to the groovy endorsed modules.</li> <li><code>module:</code> - <String> - The name of the module to load. Translated directly to a Maven artifactId.</li> <li><code>version:</code> - <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).</li> <li><code>conf:</code> - <String>, default 'default' - The configuration or scope of the module to download. The default conf is <code>default:</code> which maps to the maven <code>runtime</code> and <code>master</code> scopes.</li> <li><code>force:</code>- <boolean>, defaults true - Used to indicate that this revision must be used in case of conflicts, independently of</li> <li>conflicts manager</li> <li><code>changing:</code> - <boolean>, default false - Whether the artifact can change without it's version designation changing.</li> <li><code>transitive:</code> - <boolean>, default true - Whether to resolve other dependencies this module has or not.</li> </ul> <p>There are two principal variants of <code>grab</code>, 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.</p> <p>There are synonyms for these parameters. Submitting more than one is a runtime exception.</p> <ul> <li><code>group:</code>, <code>groupId:</code>, <code>organisation:</code>, <code>organization:</code>, <code>org:</code></li> <li><code>module:</code>, <code>artifactId:</code>, <code>artifact:</code></li> <li><code>version:</code>, <code>revision:</code>, <code>rev:</code></li> <li><code>conf:</code>, <code>scope:</code>, {{configuration:}}<blockquote><p>Grape may want support simple ranges ('2.2.1'..'*') or '2.2.1'..<'3.0.0' meaning any version greater than 2.2.1 but no 3.x version. But there are implementation problems, trying either of these ranges creates a runtime error having to do with enumerating the list.</p></blockquote></li> </ul> <h5>Arguments Map arguments</h5> <ul> <li><code>classLoader:</code> - <GroovyClassLaoder> or <RootClassLoader> - The ClassLoader to add resolved Jars to</li> <li><code>refObject:</code> - <Object> - The closest parent ClassLoader for the object's class will betreated as though it were passed in as <code>classLoader:</code></li> <li><code>validate:</code> - <boolean>, default false - Should poms or ivy files be validated (true), or should we trust the cache (false).</li> <li><code>noExceptions:</code> - <boolean>, default false - If ClassLoader resolution or repository querying fails, should we throw an exception (false) or fail silently (true).</li> </ul> <h2>Tool level support</h2> <h3><code>GroovyStarter</code></h3> <p><code>GroovyStarter</code> has been enhanced with an additonal <code>--grab</code> option. All three main arguments are required (group, module, version). Resolved jars will be added to the <code>RootLoader</code>. These modules will be resolved prior to the main class call.</p> <h3><code>LoaderConfiguration</code> conf files</h3> <p><code>LoaderConfiguration</code> has been enhanced with an additional 'grab' line option, where the option is followed by all three arguments (group, module, version). Resolved jars will be added as though they were specifically mentioned by a 'load' line option. These lines are similarly subject to property replacement as 'load' lines are.</p> <h3><code><groovyc></code> support</h3> <p>The GroovyC ant task has been enhanced with <code><grab></code> child elements. The attributes <code>group</code>, <code>module</code>, and <code>version</code> specify the module to grab.</p> <blockquote><p>TODO: currently this doesn't work when fork='true'</p></blockquote> <h2>File Level View</h2> <p>The downloaded modules will be stored according to Ivy's standard mechanism with a cache root of <code>~/.groovy/grape</code></p> <h2>Command Line Tools</h2> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>grape install <groupId> <artifactId> [<version>] </pre></td></tr></table> <p>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).</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>grape list </pre></td></tr></table> <p>Lists locally installed modules (with their full maven name in the case of groovy modules) and versions.</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>grape resolve (<groupId> <artifactId> <version>)+ </pre></td></tr></table> <p>This returns the file locations of the jars representing the artifcats for the specified module(s) and the respective transitive dependencies.</p> <h1>Motivation</h1> <p>The motivation for introducing Grape into groovy is to resolve the library and module proliferation problem we are encountering. As a general purpose language Grape is suitable for a lot of wildly variable tasks. Providing groovy ways to do those things can crate 'bloat' because a large number of classes that are</p> <h1>Rational</h1> <p>Credit for coming up with the name Grape goes to Jörg Staudemeyer and grab Andres Almiray.</p> <h2>Use of Maven Repositories</h2> <p>Maven is big, there are tons of Java libraries that are already deployed in a well-known infrastructure. Because almost all<img class="emoticon emoticon-question" data-emoticon-name="question" border="0" src="/s/en_GB/3278/15/_/images/icons/emoticons/help_16.png" alt="(question)" title="(question)" /> of these are straight Java they are all usable in Groovy out of the box.</p> <h2>Use of Ivy</h2> <ul> <li>Ivy is licensed under the ASL2, which is the same license as Groovy</li> <li>Ivy is focused strictly on Repository Management. Maven has a strong Repository Management portion, but also has other aspects not germane to the needs of the Grape system, namely build management and project management. If the goal is to provide a means to drop unneeded code we shouldn't bring in unneeded code.</li> <li>Ivy provides for an extensible repository resolution system. If we decide to roll our own Groovy Repository we have the infrastructure to do it, we can also support other non-maven repository systems if needed.</li> </ul> <h1>Backward Compatibility</h1> <p>GroovyStarter does do some existing library management, namely loading every singe jar in ~/.groovy/lib into the RootLoader. With Grape installed such behavior can continue, and is merely duplicate effort with no adverse implications. In the 2.0 timeframe we may want to look into deprecating or removing the auto-include of the ~/groovy/lib directory.</p> <h1>Reference Implementaion</h1> <p><a class="confluence-link unresolved" data-filename="grape-ivy-0.1.0.zip" data-linked-resource-default-alias="grape-ivy-0.1.0.zip" href="#">A 0.1.0 protptype is available</a>. This shows the <code>grab(...)</code> method, the <code>@Grab</code> annotation, and command line tools. Examples are available in subversion in <a href="http://svn.codehaus.org/groovy/trunk/groovy/modules/grape-ivy/src/examples/">src/examples</a>, except for the annotation, where the best examples are in the <a href="http://svn.codehaus.org/groovy/trunk/groovy/modules/grape-ivy/src/test/groovy/grape/GrapeClassLoaderTest.groovy">test class</a>.</p> <p>This version may conflict with Gant, only one of the Ivy files should exist under <code>$GROOVY_HOME/libs</code>. If the beta-1 jar is left in place then Grape may not work.</p> <h1>Future Directions</h1> <p>We may want to increase the kind of repositories that Grape can handle from simple Ivy and Maven repositories to other areas such as OSGi Repository Bundles , JNLP (WebStart) files and JSR-277 JAM files.</p>
Please type the word appearing in the picture.
Attachments
Labels
Location
Watch this page
< Edit
Preview >
Loading…
Save
Cancel
Next hint
search
attachments
weblink
advanced