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
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
<h3>Introduction</h3> <p>Recent version of Ant have included a mechanism called <a href="http://ant.apache.org/manual/CoreTypes/antlib.html">Antlibs</a>. These allow you to define your own custom tasks, group them together with the appropriate definitions needed by Ant and use them in your Ant environment without nameclashes. Nameclashes are avoided by using namespaces. Numerous Antlibs are now available from both Apache (the developers of Ant) and other sources. Using these libraries with Groovy is fairly easy - though you have to be careful with some of the details.</p> <h3>AntUnit</h3> <p>The <a href="http://ant.apache.org/antlibs/antunit">AntUnit</a> antlib includes predefined <assert> tasks corresponding to the most common kind of checks you want to do within your build files. They are using thoughout the Ant codebase to test many of the ant tasks but you can use these assertions in your own build files (or any Groovy code) too.</p> <p>Here is an example the uses the <code>assertFileDoesntExist</code> and <code>assertFileExists</code> checks.</p> <p>First, we'll consider the traditional way of incorporating this antlib, by using namespaces (you'll need the antunit jar in your classpath before you begin - as we are relying on Ant's autodiscovery of antlibs mechanism here):</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> def ant = new AntBuilder() ant.'antlib:org.apache.ant.antunit:assertFileDoesntExist'(file:'copytest1.tmp') ant.copy(file:'src/antunit.groovy', tofile:'copytest1.tmp') ant.'antlib:org.apache.ant.antunit:assertFileExists'(file:'copytest1.tmp') ant.delete(file:'copytest1.tmp') ant.'antlib:org.apache.ant.antunit:assertFileDoesntExist'(file:'copytest1.tmp') </pre></td></tr></table> <p>Notice that the antunit assertions all exist within their own namespace. That's OK for now, Groovy allows special symbols in method names so long as you include the method name in quotes.</p> <p>We can also incorporate the antlib directly into the default namespace 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> import org.apache.tools.ant.taskdefs.Antlib def ant = new AntBuilder() def url = this.class.getResource('org/apache/ant/antunit/antlib.xml') Antlib.createAntlib(ant.antProject, url, 'antlib:org.apache.ant.antunit').execute() ant.assertFileDoesntExist(file:'copytest1.tmp') ant.copy(file:'src/antunit.groovy', tofile:'copytest1.tmp') ant.assertFileExists(file:'copytest1.tmp') ant.delete(file:'copytest1.tmp') ant.assertFileDoesntExist(file:'copytest1.tmp') </pre></td></tr></table> <p>This makes our code look simpler for this example but be careful with this approach though as you need to avoid name clashes. The preferred way is to use the NamespaceBuilder. Using this, our code becomes:</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 groovy.xml.NamespaceBuilder def ant = new AntBuilder() def antunit = NamespaceBuilder.newInstance(ant, 'antlib:org.apache.ant.antunit') def destfile = 'copytest1.tmp' antunit.assertFileDoesntExist(file:destfile) ant.copy(file:'src/antunit.groovy', tofile:destfile) antunit.assertFileExists(file:destfile) ant.delete(file:destfile) antunit.assertFileDoesntExist(file:destfile) </pre></td></tr></table> <h3>Maven Ant Tasks</h3> <p>Another useful antlib is the <a href="http://maven.apache.org/ant-tasks.html">Maven Ant Tasks</a>. They allow you to use Maven's artifact handling features from within Ant including:</p> <ul> <li>Dependency management - including transitive dependencies, scope recognition and SNAPSHOT handling</li> <li>Artifact deployment - file and SSH based deployment to a Maven repository</li> <li>POM processing - for reading a Maven 2.0.x pom.xml file</li> </ul> <p>Here is how you could use these tasks to download some required jars into your local maven repository cache (<code>~/.m2</code> directory).</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 groovy.xml.NamespaceBuilder def ant = new AntBuilder() items = [[groupId:'jfree', artifactId:'jfreechart', version:'1.0.5'], [groupId:'jfree', artifactId:'jcommon', version:'1.0.9']] def mvn = NamespaceBuilder.newInstance(ant, 'antlib:org.apache.maven.artifact.ant') // download artifacts mvn.dependencies(filesetId:'artifacts') { items.each { dependency(it) } } // print out what we downloaded ant.fileScanner { fileset(refid:'artifacts') }.each { println it } </pre></td></tr></table> <p>When run, this produces a log of the maven ant task activity, such as:</p> <table class="wysiwyg-macro" data-macro-name="noformat" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e25vZm9ybWF0fQ&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> Downloading: jfree/jfreechart/1.0.5/jfreechart-1.0.5.pom ... Transferring 298K C:\Users\Paul\.m2\repository\jfree\jcommon\1.0.9\jcommon-1.0.9.jar C:\Users\Paul\.m2\repository\jfree\jfreechart\1.0.5\jfreechart-1.0.5.jar </pre></td></tr></table> <p>We can take this example further and show how to create the JFreeChart example from <a class="confluence-link" href="/display/GROOVY/Plotting+graphs+with+JFreeChart" data-linked-resource-id="68700" data-linked-resource-type="page" data-linked-resource-default-alias="Plotting graphs with JFreeChart" data-base-url="http://docs.codehaus.org">Plotting graphs with JFreeChart</a> without having the JFreeChart jars statically defined in our classpath.</p> <p>First another helper class:</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> class MavenDependency { static void require(params) { MavenDependencyHelper.getInstance().require(params) } static MavenDependencyHelper using(classLoader) { MavenDependencyHelper.getInstance(classLoader) } } private class MavenDependencyHelper { private classLoader private MavenDependencyHelper(classLoader) { this.classLoader = classLoader } static MavenDependencyHelper getInstance(classLoader) { return new MavenDependencyHelper(classLoader) } static MavenDependencyHelper getInstance() { return new MavenDependencyHelper(MavenDependencyHelper.classLoader) } MavenDependencyHelper require(params) { def ant = new AntBuilder() def mvn = groovy.xml.NamespaceBuilder.newInstance(ant, 'antlib:org.apache.maven.artifact.ant') mvn.dependencies(filesetId:"artifact_${params.groupId}_${params.artifactId}_${params.version}") { dependency(params) } ant.fileScanner { fileset(refid:"artifact_${params.groupId}_${params.artifactId}_${params.version}") }.each { classLoader.addClasspath(it.toString()) } this } } </pre></td></tr></table> <p>Now, here is the code we require to dynamically download the JFreeChart jars and add them to our classpath then run the script:</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> // no jfreechart imports required (we'll find them programmatically) import groovy.swing.SwingBuilder import static javax.swing.WindowConstants.EXIT_ON_CLOSE def classLoader = Thread.currentThread().contextClassLoader // load jars and add to classpath def maven = MavenDependency.using(classLoader) maven.require(groupId:'jfree', artifactId:'jfreechart', version:'1.0.5') maven.require(groupId:'jfree', artifactId:'jcommon', version:'1.0.9') // define used classes/instances programmatically def factoryClass = classLoader.loadClass('org.jfree.chart.ChartFactory') def orientationClass = classLoader.loadClass('org.jfree.chart.plot.PlotOrientation') def dataset = classLoader.loadClass('org.jfree.data.category.DefaultCategoryDataset').newInstance() // normal code below here dataset.addValue 150, "no.1", "Jan" dataset.addValue 210, "no.1", "Feb" dataset.addValue 390, "no.1", "Mar" dataset.addValue 300, "no.2", "Jan" dataset.addValue 400, "no.2", "Feb" dataset.addValue 200, "no.2", "Mar" def labels = [ "Bugs", "Month", "Count" ] def options = [true, true, true] def chart = factoryClass.createLineChart(*labels, dataset, orientationClass.VERTICAL, *options) def swing = new SwingBuilder() def frame = swing.frame(title:'Groovy LineChart', defaultCloseOperation:EXIT_ON_CLOSE) { panel(id:'canvas') { rigidArea(width:400, height:400) } } frame.pack() frame.show() chart.draw(swing.canvas.graphics, swing.canvas.bounds) </pre></td></tr></table> <h3>Ivy Tasks</h3> <p>We can also download jars using <a href="http://incubator.apache.org/ivy/">Ivy</a>. In this case we use <code>MarkupBuilder</code> to build an XML file that the Ivy <code>retrieve</code> task will use:</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 groovy.xml.NamespaceBuilder def ant = new AntBuilder() def ivyfile = 'ivy.xml' // default file used by Ivy ant.delete(file:ivyfile, quiet:true) new File(ivyfile).withWriter { writer -> def builder = new groovy.xml.MarkupBuilder(writer) builder.'ivy-module'(version:'1.0') { info(organisation:"codehaus", module:"GroovyExamples") dependencies { dependency(org:'jfree', name:'jfreechart', rev:'1.0.5') dependency(org:'jfree', name:'jcommon', rev:'1.0.9') } } } def ivy = NamespaceBuilder.newInstance(ant, 'antlib:org.apache.ivy.ant') ivy.retrieve() ivy.report(toDir:'reports') // optional </pre></td></tr></table> <p>When run, this results in the files being downloaded:</p> <table class="wysiwyg-macro" data-macro-name="noformat" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e25vZm9ybWF0fQ&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> [antlib:org.apache.ivy.ant:retrieve] :: Ivy 2.0.0-alpha-1-incubating - 20070416155158 ... [antlib:org.apache.ivy.ant:retrieve] downloading http://repo1.maven.org/maven2/jfree/jfreechart/1.0.5/jfreechart-1.0.5.jar ... [antlib:org.apache.ivy.ant:retrieve] [SUCCESSFUL ] [ jfree | jfreechart | 1.0.5 ]/jfreechart.jar[jar] (16735ms) [antlib:org.apache.ivy.ant:retrieve] downloading http://repo1.maven.org/maven2/jfree/jcommon/1.0.9/jcommon-1.0.9.jar ... [antlib:org.apache.ivy.ant:retrieve] [SUCCESSFUL ] [ jfree | jcommon | 1.0.9 ]/jcommon.jar[jar] (6812ms) [antlib:org.apache.ivy.ant:retrieve] :: resolution report :: --------------------------------------------------------------------- | | modules || artifacts | | conf | number| search|dwnlded|evicted|| number|dwnlded| --------------------------------------------------------------------- | default | 2 | 2 | 0 | 0 || 2 | 2 | --------------------------------------------------------------------- [antlib:org.apache.ivy.ant:retrieve] :: retrieving :: [ codehaus | grails ] [antlib:org.apache.ivy.ant:retrieve] confs: [default] [antlib:org.apache.ivy.ant:retrieve] 2 artifacts copied, 0 already retrieved </pre></td></tr></table> <p>If you included the optional <code>report</code> step (and add ant-trax.jar from your ant distribution to our classpath), then you would have some additional log information and it would produce the following pretty report on dependencies:</p> <p><img class="confluence-embedded-image" src="/download/attachments/230400671/IvyReport.gif?version=1&modificationDate=1368925782669" data-image-src="/download/attachments/230400671/IvyReport.gif?version=1&modificationDate=1368925782669" data-linked-resource-id="230565008" data-linked-resource-type="attachment" data-linked-resource-default-alias="IvyReport.gif" data-base-url="http://docs.codehaus.org" data-linked-resource-container-id="230400671" title="null > IvyReport.gif"></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