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
<table class="wysiwyg-macro" data-macro-name="info" data-macro-parameters="title=InfoQ" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2luZm86dGl0bGU9SW5mb1F9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="RICH_TEXT"><tr><td class="wysiwyg-macro-body"><p>Article originally <a href="http://www.infoq.com/articles/groovy-1-6">published on InfoQ</a></p></td></tr></table><p><a href="http://groovy.codehaus.org/">Groovy</a> is a very successful and powerful <strong>dynamic language for the Java Virtual Machine</strong> that provides <strong>seamless integration with Java</strong>, and has its roots firmly planted in Java itself for the syntax and APIs and other languages such as Smalltalk, Python or Ruby for its dynamic capabilities.</p><div class="content-sidebar-wide"><div class="vendor-content-box-float"><h3><span style="font-size: 10.0pt;font-weight: normal;line-height: 13.0pt;">Groovy is used in many Open Source projects such as </span><a href="http://grails.org/" style="font-size: 10.0pt;font-weight: normal;line-height: 13.0pt;">Grails</a><span style="font-size: 10.0pt;font-weight: normal;line-height: 13.0pt;">, </span><a href="http://www.springframework.org/" style="font-size: 10.0pt;font-weight: normal;line-height: 13.0pt;">Spring</a><span style="font-size: 10.0pt;font-weight: normal;line-height: 13.0pt;">, JBoss Seam and more, as well as </span><strong style="font-size: 10.0pt;line-height: 13.0pt;">integrated in commercial products</strong><span style="font-size: 10.0pt;font-weight: normal;line-height: 13.0pt;"> and </span><strong style="font-size: 10.0pt;line-height: 13.0pt;">Fortune 500 mission-critical applications</strong><span style="font-size: 10.0pt;font-weight: normal;line-height: 13.0pt;"> for its scripting capabilities offering a nice extension mechanism to these applications, or for its ability to let subject matter experts and developers author embedded Domain-Specific Languages to </span><strong style="font-size: 10.0pt;line-height: 13.0pt;">express business concepts in a readable and maintainable fashion</strong><span style="font-size: 10.0pt;font-weight: normal;line-height: 13.0pt;">.</span></h3></div></div><p>In this article, <a href="http://www.springsource.com/people/glaforge">Guillaume Laforge</a>, Groovy Project Manager and Head of Groovy Development at <a href="http://www.springsource.com/">SpringSource</a>, will go through an overview of the novelties offered by the newly released Groovy 1.6.</p><h2>Overview of Groovy 1.6</h2><p>As we shall see in this article, the main highlights of this Groovy 1.6 release are:</p><ul><li><strong>Greater compile-time and runtime performance improvements</strong></li><li>Multiple assignments</li><li>Optional return in <code>if</code>/<code>else</code> and <code>try</code>/<code>catch</code> blocks</li><li>Java 5 annotation definition</li><li><strong>AST transformations</strong> and all the provided transformation annotations like<code>@Singleton</code>, <code>@Lazy</code>, <code>@Immutable</code>, <code>@Delegate</code> and friends</li><li>The Grape module and dependency system and its <code>@Grab</code> transformation</li><li>Various Swing builder improvements, thanks to the Swing / <a href="http://griffon.codehaus.org/">Griffon</a> team, as well as several Swing console improvements</li><li>The integration of <strong>JMX builder</strong></li><li>Various <strong>metaprogramming improvements</strong>, like the EMC DSL, per-instance metaclasses even for POJOs, and runtime mixins</li><li><strong>JSR-223</strong> scripting engine built-in</li><li>Out-of-the-box <strong>OSGi readiness</strong></li></ul><p>All those improvements and new features serve one goal: <strong>helping developers be more productive and more agile</strong>, by:</p><ul><li>Focusing more on the task at hand than on boiler-plate technical code</li><li>Leveraging existing Enterprise APIs rather than reinventing the wheel</li><li>Improving the overal performance and quality of the language</li><li>Enabling developers to customize the language at will to derive their own Domain-Specific Languages</li></ul><p>But beyond all these important aspects, <strong>Groovy is not just a language, it's a whole ecosystem</strong>.</p><p>The improvements in Groovy's generated bytecode information helps capable tools coverage like <a href="http://docs.codehaus.org/display/GROOVY/Test+Coverage">Cobertura</a> and its Groovy support, or pave the way for new utilities like <a href="http://codenarc.sourceforge.net/">CodeNarc</a> for static code analysis for Groovy.</p><p>The malleability of the syntax of the language and its metaprogramming capabilities give birth to advanced testing tools such as the<a href="http://easyb.org/">Easyb</a> Behavior-Driven-Development project, the <a href="http://code.google.com/p/gmock/">GMock</a> mocking library or the <a href="http://code.google.com/p/spock/">Spock</a> testing and specification framework.</p><p>Again, Groovy's flexibility and expressivity and its scripting capabilities open the doors to advanced build scripting or infrastructure systems for your continuous integration practices and project build solutions, such as <a href="http://gant.codehaus.org/">Gant</a> and <a href="http://www.gradle.org/">Graddle</a>.</p><p>At the tooling level, Groovy also progresses, for instance with its <code>groovydoc</code> Ant task to let you generate proper JavaDoc covering, documenting and interlinking both your Groovy and Java source files for your Groovy/Java mixed projects.</p><p>And at the same time, IDE makers improve their support for Groovy, by giving users powerful weapons such as cross-language code refactoring, profound understanding of dynamic language idioms, code completion, and more, to make developers productive when using Groovy in their projects.</p><p>Now, armed with this knowledge of the Groovy world, it's time to dive into the novelties of Groovy 1.6!</p><h2>Performance improvements</h2><p>A lot of care has been taken to improve both the compile-time and runtime performance of Groovy, compared to previous releases.</p><p>The <strong>compiler is 3 to 5 times faster</strong> than in previous releases. This improvement has also been backported in the 1.5.x branch, so that both the old maintenance branch and the current stable branch benefit from this work. Thanks to class lookup caches, the bigger the project, the faster the compilation will be.</p><p>However, the most noticeable changes will be in the general runtime performance improvements of Groovy. We used several benchmarks from the <a href="http://shootout.alioth.debian.org/">Great Language Shootout</a> to measure our progress. On those we selected, compared to the old Groovy 1.5.x line, the<strong>performance improvements ranged from 150% to 460%</strong>. Micro-benchmarks obviously rarely reflect the kind of code you have in your own projects, but the overal performance of your projects should improve significantly.</p><h2>Multiple assignments</h2><p>In Groovy 1.6, there is only one syntax addition for being able to define and assign several variables at once:</p><pre><strong>def</strong> (a, b) = [1, 2] <strong>assert</strong> a == 1 <strong>assert</strong> b == 2 </pre><p>A more meaninful example may be methods returning longitute and latitude coordinates. If these coordinates are represented as a list of two elements, you can easily get back to each element as follows:</p><pre><strong>def</strong> geocode(String location) { // implementation returns [48.824068, 2.531733] for Paris, France } <strong>def</strong> (lat, long) = geocode("Paris, France") <strong>assert</strong> lat == 48.824068 <strong>assert</strong> long == 2.531733 </pre><p>And you can also define the types of the variables in one shot as follows:</p><pre><strong>def</strong> (<strong>int</strong> i, String s) = [1, 'Groovy'] <strong>assert</strong> i == 1 <strong>assert</strong> s == 'Groovy' </pre><p>For the assignment (with prior definition of the variables), just omit the <code>def</code> keyword:</p><pre><strong>def</strong> firstname, lastname (firstname, lastname) = "Guillaume Laforge".tokenize() <strong>assert</strong> firstname == "Guillaume" <strong>assert</strong> lastname == "Laforge" </pre><p>If the list on the right-hand side contains more elements than the number of variables on the left-hand side, only the first elements will be assigned in order into the variables. Also, when there are less elements than variables, the extra variables will be assigned null.</p><p>So for the case with more variables than list elements, here, <code>c</code> will be <code>null</code>:</p><pre><strong>def</strong> elements = [1, 2] <strong>def</strong> (a, b, c) = elements <strong>assert</strong> a == 1 <strong>assert</strong> b == 2 <strong>assert</strong> c == null </pre><p>Whereas in the case where there are more list elements than variables, we'll get the following expectations:</p><pre><strong>def</strong> elements = [1, 2, 3, 4] <strong>def</strong> (a, b, c) = elements <strong>assert</strong> a == 1 <strong>assert</strong> b == 2 <strong>assert</strong> c == 3 </pre><p>For the curious minds, supporting multiple assignments also means we can do the standard school swap case in one line:</p><pre>// given those two variables <strong>def</strong> a = 1, b = 2 // swap variables with a list (a, b) = [b, a] <strong>assert</strong> a == 2 <strong>assert</strong> b == 1 </pre><h2>Annotation definition</h2><p>Actually, when I said that multiple assignments were the sole syntax addition, it's not entirely true. Groovy supported the syntax for annotation definition even in Groovy 1.5, but we had not implemented the feature completely. Fortunately, this is now fixed, and it wraps up all the Java 5 features supported by Groovy, such as <strong>static imports</strong>, <strong>generics</strong>, <strong>annotations</strong>, and <strong>enums</strong>, making Groovy the <strong>sole alternative dynamic language for the JVM supporting all those Java 5 features</strong>, which is critical for a seamless Java integration story, and for the usage in Enterprise frameworks relying on annotations, generics and more, like JPA, EJB3, Spring, TestNG, etc.</p><h2>Optional return for if/else and try/catch/finally blocks</h2><p>It is now possible for <code>if/else</code> and <code>try/catch/finally</code> blocks to return a value when they are the last expression in a method or a closure. No need to explicitly use the <code>return</code> keyword inside these constructs, as long as they are the latest expression in the block of code.</p><p>As an example, the following method will return <code>1</code>, although the <code>return</code> keyword was omitted.</p><pre><strong>def</strong> method() { <strong>if</strong> (<strong>true</strong>) 1 <strong>else</strong> 0 } <strong>assert</strong> method() == 1 </pre><p>For <code>try/catch/finally</code> blocks, the last expression evaluated is the one being returned. If an exception is thrown in the <code>try</code> block, the last expression in the <code>catch</code> block is returned instead. Note that <code>finally</code> blocks don't return any value.</p><pre><strong>def</strong> method(bool) { <strong>try</strong> { <strong>if</strong> (bool) <strong>throw</strong> <strong>new</strong> Exception("foo") 1 } <strong>catch</strong>(e) { 2 } <strong>finally</strong> { 3 } } <strong>assert</strong> method(<strong>false</strong>) == 1 <strong>assert</strong> method(<strong>true</strong>) == 2 </pre><h2>AST Transformations</h2><p>Although at times, it may sound like a good idea to extend the syntax of Groovy to implement new features (like this is the case for instance for multiple assignments), most of the time, we can't just add a new keyword to the grammar, or create some new syntax construct to represent a new concept. However, with the idea of AST (Abstract Syntax Tree) Transformations, we are able to tackle new and innovative ideas without necessary grammar changes.</p><p>When the Groovy compiler compiles Groovy scripts and classes, at some point in the process, the source code will end up being represented in memory in the form of a Concrete Syntax Tree, then transformed into an Abstract Syntax Tree. The purpose of AST Transformations is to let developers hook into the compilation process to be able to modify the AST before it is turned into bytecode that will be run by the JVM.</p><p><strong>AST Transformations provides Groovy with improved compile-time metaprogramming capabilities</strong> allowing powerful flexibility at the language level, without a runtime performance penalty.</p><p>There are two kinds of transformations: global and local transformations.</p><ul><li>Global transformations are applied to by the compiler on the code being compiled, wherever the transformation apply. A JAR added to the classpath of the compiler should contain a service locator file at <code>META-INF/services/org.codehaus.groovy.transform.ASTTransformation</code> with a line with the name of the transformation class. The transformation class must have a no-args constructor and implement the <code>org.codehaus.groovy.transform.ASTTransformation</code>interface. It will be run against every source in the compilation, so be sure to not create transformations which scan all the AST in an expansive and time-consuming manner, to keep the compiler fast.</li><li>Local transformations are transformations applied locally by annotating code elements you want to transform. For this, we reuse the annotation notation, and those annotations should implement <code>org.codehaus.groovy.transform.ASTTransformation</code>. The compiler will discover them and apply the transformation on these code elements.</li></ul><p> </p><p>Groovy 1.6 provides several local transformation annotations, in the Groovy Swing Builder for data binding (<code>@Bindable</code> and <code>@Vetoable</code>), in the Grape module system for adding script library dependencies (<code>@Grab</code>), or as general language features without requiring any syntax change to support them (<code>@Singleton</code>, <code>@Immutable</code>, <code>@Delegate</code>, <code>@Lazy</code>, <code>@Newify</code>, <code>@Category</code>, <code>@Mixin</code> and <code>@PackageScope</code>). Let's have a look at some of these transformations (<code>@Bindable</code> and <code>@Vetoable</code> will be covered in the section related to the Swing enhancements, and <code>@Grab</code> in the section about Grape).</p><h3>@Singleton</h3><p>Whether the singleton is pattern or an anti-pattern, there are still some cases where we need to create singletons. We're used to create a private constructor, a <code>getInstance()</code> method for a static field or even an initialized <code>public static final</code> field. So instead of writing code like this in Java:</p><pre><strong>public</strong> <strong>class</strong> T { <strong>public static final</strong> T instance = <strong>new</strong> T(); <strong>private</strong> T() {} } </pre><p>You just need to annotate your type with the <code>@Singleton</code> annotation:</p><pre>@Singleton <strong>class</strong> T {} </pre><p>The singleton instance can then simply be accessed with <code>T.instance</code> (direct public field access).</p><p>You can also have the lazy loading approach with an additional annotation parameter:</p><pre>@Singleton(lazy = <strong>true</strong>) <strong>class</strong> T {} </pre><p>Would become more or less equivalent to this Groovy class:</p><pre><strong>class</strong> T { <strong>private static volatile</strong> T instance <strong>private</strong> T() {} <strong>static</strong> T getInstance () { <strong>if</strong> (instance) { instance } <strong>else</strong> { <strong>synchronized</strong>(T) { <strong>if</strong> (instance) { instance } <strong>else</strong> { instance = <strong>new</strong> T () } } } } } </pre><p>Lazy or not, once again, to access the instance, simply do <code>T.instance</code> (property access, shorcut for <code>T.getInstance()</code>).</p><h3>@Immutable</h3><p>Immutable objects are ones which don't change after initial creation. Such objects are frequently desirable because they are simple and can be safely shared even in multi-threading contexts. This makes them great for functional and concurrent scenarios. The rules for creating such objects are well-known:</p><ul><li>No mutators (methods that modify internal state)</li><li>Class must be final</li><li>Fields must be private and final</li><li>Defensive copying of mutable components</li><li><code>equals()</code>, <code>hashCode()</code> and <code>toString()</code> must be implemented in terms of the fields if you want to compare your objects or use them as keys in e.g. maps</li></ul><p>Instead of writing a very long Java or Groovy class mimicking this immutability behavior, Groovy lets you just write an immutable class as follow:</p><p> </p><pre>@Immutable <strong>final class</strong> Coordinates { Double latitude, longitude } <strong>def</strong> c1 = <strong>new</strong> Coordinates(latitude: 48.824068, longitude: 2.531733) <strong>def</strong> c2 = <strong>new</strong> Coordinates(48.824068, 2.531733) <strong>assert</strong> c1 == c2 </pre><p>All the boiler-plate code is generated at compile-time for you! The example shows that to instantiate such immutable coordinates, you can use one of the two constructors created by the transformation, one taking a map whose keys are the properties to set to the values associated with those keys, and the other taking the values of the properties as parameters. The <code>assert</code> also shows that <code>equals()</code> was implemented and allows us to properly compare such immutable objects.</p><p>You can have a look at the <a href="http://groovy.codehaus.org/Immutable+AST+Macro">details of the implementation</a> of this transformation. For the record, the Groovy example above using the<code>@Immutable</code> transformation is over 50 lines of equivalent Java code.</p><h3>@Lazy</h3><p>Another transformation is <code>@Lazy</code>. Sometimes, you want to handle the initialization of a field of your clas lazily, so that its value is computed only on first use, often because it may be time-consuming or memory-expensive to create. The usual approach is to customize the getter of said field, so that it takes care of the initialization when the getter is called the first time. But in Groovy 1.6, you can now use the <code>@Lazy</code> annotation for that purpose:</p><pre><strong>class</strong> Person { @Lazy pets = ['Cat', 'Dog', 'Bird'] } <strong>def</strong> p = <strong>new</strong> Person() <strong>assert</strong> !(p.dump().contains('Cat')) <strong>assert</strong> p.pets.size() == 3 <strong>assert</strong> p.dump().contains('Cat') </pre><p>In the case of complex computation for initializing the field, you may need to call some method for doing the work, instead of a value like our pets list. This is then possible to have the lazy evaluation being done by a closure call, as the following example shows:</p><pre><strong>class</strong> Person { @Lazy List pets = { /* complex computation here */ }() } </pre><p>There is also an option for leveraging Soft references for garbage collection friendliness for expensive data structures that may be contained by such lazy fields:</p><pre><strong>class</strong> Person { @Lazy(soft = true) List pets = ['Cat', 'Dog', 'Bird'] } <strong>def</strong> p = <strong>new</strong> Person() <strong>assert</strong> p.pets.contains('Cat') </pre><p>The internal field created by the compiler for <code>pets</code> will actually be a Soft reference, but accessing <code>p.pets</code> directly will return the value (ie. the list of pets) held by that reference, making the use of the soft reference transparent to the user of that class.</p><h3>@Delegate</h3><p>Java doesn't provide any built-in delegation mechanism, and so far Groovy didn't either. But with the <code>@Delegate</code> transformation, a class field or property can be annotated and become an object to which method calls are delegated. In the following example, an <code>Event</code> class has a date delegate, and the compiler will delegate all of <code>Date</code>'s methods invoked on the <code>Event</code> class to the <code>Date</code> delegate. As shown in the latest <code>assert</code>, the <code>Event</code> class has got a <code>before(Date)</code> method, and all of <code>Date</code>'s methods.</p><pre><strong>import</strong> java.text.SimpleDateFormat <strong>class</strong> Event { @Delegate Date when String title, url } <strong>def</strong> df = <strong>new</strong> SimpleDateFormat("yyyy/MM/dd") <strong>def</strong> gr8conf = <strong>new</strong> Event(title: "GR8 Conference", url: "<a href="http://www.gr8conf.org/">http://www.gr8conf.org</a>", when: df.parse("2009/05/18")) <strong>def</strong> javaOne = <strong>new</strong> Event(title: "JavaOne", url: "<a href="http://java.sun.com/javaone/">http://java.sun.com/javaone/</a>", when: df.parse("2009/06/02")) assert gr8conf.before(javaOne.when) </pre><p>The Groovy compiler adds all of <code>Date</code>'s methods to the <code>Event</code> class, and those methods simply delegate the call to the <code>Date</code> field. If the delegate is not a final class, it is even possible to make the <code>Event</code> class a subclass of <code>Date</code> simply by extending <code>Date</code>, as shown below. No need to implement the delegation ourselves by adding each and every <code>Date</code> methods to our <code>Event</code> class, since the compiler is friendly-enough with us to do the job itself.</p><pre><strong>class</strong> Event <strong>extends</strong> Date { @Delegate Date when String title, url } </pre><p>In the case you are delegating to an interface, however, you don't even need to explictely say you implement the interface of the delegate. The <code>@Delegate</code> transformation will take care of this and implement that interface. So the instances of your class will automatically be <code>instanceof</code> the delegate's interface.</p><pre><strong>import</strong> java.util.concurrent.locks.* <strong>class</strong> LockableList { @Delegate <strong>private</strong> List list = [] @Delegate <strong>private</strong> Lock lock = <strong>new</strong> ReentrantLock() } <strong>def</strong> list = <strong>new</strong> LockableList() list.lock() <strong>try</strong> { list << 'Groovy' list << 'Grails' list << 'Griffon' } <strong>finally</strong> { list.unlock() } <strong>assert</strong> list.size() == 3 <strong>assert</strong> list <strong>instanceof</strong> Lock <strong>assert</strong> list <strong>instanceof</strong> List </pre><p>In this example, our <code>LockableList</code> is now a composite of a list and a lock and is <code>instanceof</code> of <code>List</code> and <code>Lock</code>. However, if you didn't intend your class to be implementing these interfaces, you would still be able to do so by specifying a parameter on the annotation:</p><pre>@Delegate(interfaces = <strong>false</strong>) <strong>private</strong> List list = [] </pre><h3>@Newify</h3><p>The <code>@Newify</code> transformation proposes two new ways of instantiating classes. The first one is providing Ruby like approach to creating instances with a <code>new()</code> class method:</p><pre>@Newify rubyLikeNew() { <strong>assert</strong> Integer.new(42) == 42 } rubyLikeNew() </pre><p>But it is also possible to follow the Python approach with omitting the <code>new</code> keyword. Imagine the following tree creation:</p><pre><strong>class</strong> Tree { <strong>def</strong> elements Tree(Object... elements) { this.elements = elements <strong>as</strong> List } } <strong>class</strong> Leaf { <strong>def</strong> value Leaf(value) { <strong>this</strong>.value = value } } <strong>def</strong> buildTree() { <strong>new</strong> Tree(<strong>new</strong> Tree(<strong>new</strong> Leaf(1), <strong>new</strong> Leaf(2)), <strong>new</strong> Leaf(3)) } buildTree() </pre><p>The creation of the tree is not very readable because of all those <code>new</code> keywords spread across the line. The Ruby approach wouldn't be more readable, since a <code>new()</code> method call for creating each element is needed. But by using <code>@Newify</code>, we can improve our tree building slightly to make it easier on the eye:</p><pre>@Newify([Tree, Leaf]) buildTree() { Tree(Tree(Leaf(1), Leaf(2)), Leaf(3)) } </pre><p>You'll also notice that we just allowed <code>Tree</code> and <code>Leaf</code> to be <em>newified</em>. By default, under the scope which is annotated, all instantiations are<em>newified</em>, but you can limit the reach by specifying the classes you're interested in. Also, note that for our example, perhaps a Groovy builder may have been more appropriate, since its purpose is to indeed create any kind of hierarchical / tree strucutre.</p><p>If we take another look at our coordinates example from a few sections earlier, using both <code>@Immutable</code> and <code>@Newify</code> can be interesting for creating a path with a concise but type-safe manner:</p><pre>@Immutable <strong>final class</strong> Coordinates { Double latitude, longitude } @Immutable <strong>final class</strong> Path { Coordinates[] coordinates } @Newify([Coordinates, Path]) <strong>def</strong> build() { Path( Coordinates(48.824068, 2.531733), Coordinates(48.857840, 2.347212), Coordinates(48.858429, 2.342622) ) } <strong>assert</strong> build().coordinates.size() == 3 </pre><p>A closing remark here: since a <code>Path(Coordinates[] coordinates)</code> was generated, we can use that constructor in a <em>varargs way</em> in Groovy, just as if it had been defined as <code>Path(Coordinates... coordinates)</code>.</p><h3>@Category and @Mixin</h3><p>If you've been using Groovy for a while, you're certainly familiar with the concept of Categories. It's a mechanism to extend existing types (even final classes from the JDK or third-party libraries), to add new methods to them. This is also a technique which can be used when writing Domain-Specific Languages. Let's consider the example below:</p><pre><strong>final class</strong> Distance { <strong>def</strong> number String toString() { "${number}m" } } <strong>class</strong> NumberCategory { <strong>static</strong> Distance getMeters(Number self) { <strong>new</strong> Distance(number: self) } } use(NumberCategory) { <strong>def</strong> dist = 300.meters <strong>assert</strong> dist <strong>instanceof</strong> Distance <strong>assert</strong> dist.toString() == "300m" } </pre><p>We have a simplistic and fictive <code>Distance</code> class which may have been provided by a third-party, who had the bad idea of making the class<code>final</code> so that nobody could ever extend it in any way. But thanks to a Groovy Category, we are able to decorate the <code>Distance</code> type with additional methods. Here, we're going to add a <code>getMeters()</code> method to numbers, by actually decorating the <code>Number</code> type. By adding a getter to a number, you're able to reference it using the nice property syntax of Groovy. So instead of writing <code>300.getMeters()</code>, you're able to write <code>300.meters</code>.</p><p>The downside of this category system and notation is that to add instance methods to other types, you have to create <code>static</code> methods, and furthermore, there's a first argument which represents the instance of the type we're working on. The other arguments are the normal arguments the method will take as parameters. So it may be a bit less intuitive than a normal method definition we would have added to <code>Distance</code>, should we have had access to its source code for enhancing it. Here comes the <code>@Category</code> annotation, which transforms a class with instance methods into a Groovy category:</p><pre>@Category(Number) <strong>class</strong> NumberCategory { Distance getMeters() { <strong>new</strong> Distance(number: <strong>this</strong>) } } </pre><p>No need for declaring the methods <code>static</code>, and the <code>this</code> you use here is actually the number on which the category will apply, it's not the real <code>this</code> of the category instance should we create one. Then to use the category, you can continue to use the <code>use(Category) {}</code>construct. What you'll notice however is that these kind of categories only apply to one single type at a time, unlike classical categories which can be applied to any number of types.</p><p>Now, pair <code>@Category</code> extensions to the <code>@Mixin</code> transformation, and you can mix in various behavior in a class, with an approach similar to multiple inheritance:</p><pre>@Category(Vehicle) <strong>class</strong> FlyingAbility { <strong>def</strong> fly() { "I'm the ${name} and I fly!" } } @Category(Vehicle) <strong>class</strong> DivingAbility { <strong>def</strong> dive() { "I'm the ${name} and I dive!" } } <strong>interface</strong> Vehicle { String getName() } @Mixin(DivingAbility) <strong>class</strong> Submarine <strong>implements</strong> Vehicle { String getName() { "Yellow Submarine" } } @Mixin(FlyingAbility) <strong>class</strong> Plane <strong>implements</strong> Vehicle { String getName() { "Concorde" } } @Mixin([DivingAbility, FlyingAbility]) <strong>class</strong> JamesBondVehicle <strong>implements</strong> Vehicle { String getName() { "James Bond's vehicle" } } <strong>assert</strong> <strong>new</strong> Plane().fly() == "I'm the Concorde and I fly!" <strong>assert</strong> <strong>new</strong> Submarine().dive() == "I'm the Yellow Submarine and I dive!" <strong>assert new</strong> JamesBondVehicle().fly() == "I'm the James Bond's vehicle and I fly!" <strong>assert new</strong> JamesBondVehicle().dive() == "I'm the James Bond's vehicle and I dive!" </pre><p>You don't inherit from various interfaces and inject the same behavior in each subclass, instead you mixin the categories into your class. Here, our marvelous James Bond vehicle gets the flying and diving capabilities through mixins.</p><p>An important point to make here is that unlike <code>@Delegate</code> which can <em>inject</em> interfaces into the class in which the delegate is declared,<code>@Mixin</code> just does runtime mixing — as we shall see in the metaprogramming enhancements further down in this article.</p><h3>@PackageScope</h3><p>Groovy's convention for properties is that any <em>field</em> without any visibility modifier is exposed as a property, with a getter and a setter transparently generated for you. For instance, this <code>Person</code> class exposes a getter <code>getName()</code> and a setter <code>setName()</code> for a private <code>name</code> field:</p><pre><strong>class</strong> Person { String name } </pre><p>Which is equivalent to this Java class:</p><pre><strong>public class</strong> Person { <strong>private</strong> String name; <strong>public</strong> String getName() { return name; } <strong>public void</strong> setName(name) { <strong>this</strong>.name = name; } } </pre><p>That said, this approach has one drawback in that you don't have the possibility to define a field with package-scope visibility. To be able to expose a field with package-scope visibility, you can now annotate your field with the <code>@PackageScope</code> annotation.</p><h2>Grape, the Groovy Adaptable / Advanced Packaging Engine</h2><p>To continue our overview of the AST transformations, we'll now learn more about Grape, a mechanism to add and leverage dependencies in your Groovy scripts. Groovy scripts can require certain libraries: by explicitly saying so in your script with the <strong>@Grab</strong> transformation or with the <strong>Grape.grab()</strong> method call, the runtime will find the needed JARs for you. With Grape, you can easily distribute scripts without their dependencies, and have them downloaded on first use of your script and cached. Under the hood, Grape uses Ivy and Maven repositories containing the libraries you may need in your scripts.</p><p>Imagine you want to get the links of all the PDF documents referenced by the Java 5 documentation. You want to parse the HTML page as if it were an XML-compliant document (which it is not) with the Groovy <code>XmlParser</code>, so you can use the TagSoup SAX-compliant parser which transforms HTML into well-formed valid XML. You don't even have to mess up with your classpath when running your script, just<em>grab</em> the TagSoup library through Grape:</p><pre><strong>import</strong> org.ccil.cowan.tagsoup.Parser // find the PDF links in the Java 1.5.0 documentation @Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7') <strong>def</strong> getHtml() { <strong>def</strong> tagsoupParser = <strong>new</strong> Parser() <strong>def</strong> parser = <strong>new</strong> XmlParser(tagsoupParser) parser.parse("http://java.sun.com/j2se/1.5.0/download-pdf.html") } html.body.'**'.a.@href.grep(~/.*\.pdf/).each{ println it } </pre><p>For the pleasure of giving another example: let's use the <a href="http://www.mortbay.org/jetty/">Jetty servlet container</a> to expose <a href="http://groovy.codehaus.org/Groovy+Templates">Groovy templates</a> in a few lines of code:</p><pre><strong>import</strong> org.mortbay.jetty.Server <strong>import</strong> org.mortbay.jetty.servlet.* <strong>import</strong> groovy.servlet.* @Grab(group = 'org.mortbay.jetty', module = 'jetty-embedded', version = '6.1.0') <strong>def</strong> runServer(duration) { <strong>def</strong> server = <strong>new</strong> Server(8080) <strong>def</strong> context = <strong>new</strong> Context(server, "/", Context.SESSIONS); context.resourceBase = "." context.addServlet(TemplateServlet, "*.gsp") server.start() sleep duration server.stop() } runServer(10000) </pre><p>Grape will download Jetty and its dependencies on first launch of this script, and cache them. We're creating a new Jetty <code>Server</code> on port 8080, then expose Groovy's <code>TemplateServlet</code> 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 <code><a href="http://localhost:8080/somepage.gsp">http://localhost:8080/somepage.gsp</a></code>, it will display the <code>somepage.gsp</code> template to the user — those template pages should be situated in the same directory as this server script.</p><p>Grape can also be used as a method call instead of as an annotation. You can also install, list, resolve dependencies from the command-line using the <code>grape</code> command. For <a href="http://groovy.codehaus.org/Grape">more information on Grape</a>, please refer to the documentation.</p><h2>Swing builder improvements</h2><p>To wrap up our overview of AST transformations, let's finish by speaking about two transformations very useful to Swing developers:<code>@Bindable</code> and <code>@Vetoable</code>. When creating Swing UIs, you're often interested in monitoring the changes of value of certain UI elements. For this purpose, the usual approach is to use JavaBeans <code>PropertyChangeListener</code>s to be notified when the value of a class field changes. You then end up writing this very common boiler-plate code in your Java beans:</p><pre><strong>import</strong> java.beans.PropertyChangeSupport; <strong>import</strong> java.beans.PropertyChangeListener; <strong>public class</strong> MyBean { <strong>private</strong> String prop; PropertyChangeSupport pcs = <strong>new</strong> PropertyChangeSupport(this); <strong>public void</strong> addPropertyChangeListener(PropertyChangeListener l) { pcs.add(l); } <strong>public void</strong> removePropertyChangeListener(PropertyChangeListener l) { pcs.remove(l); } <strong>public</strong> String getProp() { <strong>return</strong> prop; } <strong>public void</strong> setProp(String prop) { pcs.firePropertyChanged("prop", <strong>this</strong>.prop, <strong>this</strong>.prop = prop); } } </pre><p>Fortunately, with Groovy and the <code>@Bindable</code> annotation, this code can be greatly simplified:</p><pre><strong>class</strong> MyBean { @Bindable String prop } </pre><p>Now pair that with Groovy's Swing builder new <code>bind()</code> method, define a text field and bind its value to a property of your data model:</p><pre>textField text: bind(source: myBeanInstance, sourceProperty: 'prop') </pre><p>Or even:</p><pre>textField text: bind { myBeanInstance.prop } </pre><p>The binding also works with simple expressions in the closure, for instance something like this is possible too:</p><pre>bean location: bind { pos.x + ', ' + pos.y } </pre><p>You may also be interested in having a look at <a href="http://groovy.codehaus.org/api/groovy/util/ObservableMap.html">ObservableMap</a> and <a href="http://groovy.codehaus.org/api/groovy/util/ObservableList.html">ObservableList</a>, for a similar mechanism on maps and lists.</p><p>Along with <code>@Bindable</code>, there's also a <code>@Vetoable</code> transformation for when you need to be able to veto some property change. Let's consider a <code>Trompetist</code> class, where the performer's name is not allowed to contain the letter 'z':</p><pre><strong>import</strong> java.beans.* <strong>import</strong> groovy.beans.Vetoable <strong>class</strong> Trumpetist { @Vetoable String name } <strong>def</strong> me = new Trumpetist() me.vetoableChange = { PropertyChangeEvent pce -> <strong>if</strong> (pce.newValue.contains('z')) <strong>throw new</strong> PropertyVetoException("The letter 'z' is not allowed in a name", pce) } me.name = "Louis Armstrong" <strong>try</strong> { me.name = "Dizzy Gillespie" assert <strong>false</strong>: "You should not be able to set a name with letter 'z' in it." } <strong>catch</strong> (PropertyVetoException pve) { <strong>assert true</strong> } </pre><p>Looking at a more thorough Swing builder example with binding:</p><pre><strong>import</strong> groovy.swing.SwingBuilder <strong>import</strong> groovy.beans.Bindable <strong>import static</strong> javax.swing.JFrame.EXIT_ON_CLOSE <strong>class</strong> TextModel { @Bindable String text } <strong>def</strong> textModel = <strong>new</strong> TextModel() SwingBuilder.build { frame( title: 'Binding Example (Groovy)', size: [240,100], show: <strong>true</strong>, locationRelativeTo: <strong>null</strong>, defaultCloseOperation: EXIT_ON_CLOSE ) { gridLayout cols: 1, rows: 2 textField id: 'textField' bean textModel, text: bind{ textField.text } label text: bind{ textModel.text } } } </pre><p>Running this script shows up the frame below with a text field and a lable below, and the label's text is bound on the text field's content.</p><div><img class="confluence-embedded-image confluence-external-resource" src="http://www.infoq.com/resource/articles/groovy-1-6/en/resources/bindable-example.png" data-image-src="http://www.infoq.com/resource/articles/groovy-1-6/en/resources/bindable-example.png"></div><p>SwingBuilder has evolved so nicely in the past year that the Groovy Swing team decided to launch a new project based on it, and on the Grails foundations: project <a href="http://griffon.codehaus.org/">Griffon</a> was born. Griffon proposes to bring the <em>Convention over Configuration</em> paradigm of Grails, as well as all its project structure, plugin system, gant scripting capabilities, etc.</p><p>If you are developing Swing rich clients, make sure to have a look at <a href="http://griffon.codehaus.org/">Griffon</a>.</p><h2>Swing console improvements</h2><p>Swinging along the topic of UIs, the Swing console has also evolved:</p><ul><li>The console can be run as an Applet (<code>groovy.ui.ConsoleApplet</code>).</li><li>Beyond syntax highlighting, the editor also supports code indentation.</li><li>Drag'n droping a Groovy script over the text area will open the file.</li><li>You can modify the classpath with which the script in the console is being run, by adding a new JAR or a directory to the classpath as shown in the screenshot below.<div><img class="confluence-embedded-image confluence-external-resource" hspace="20" vspace="20" src="http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-add-jar.png" data-image-src="http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-add-jar.png"></div></li><li>A couple options have been added to the view menu item: for showing the script being run in the output area, and for visualizing the execution results.<div><img class="confluence-embedded-image confluence-external-resource" src="http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-options.png" data-image-src="http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-options.png"></div></li><li>When an exception is thrown in your script, the lines of the stacktrace relative to your script are clickable, for easy navigation to the point where the error occurred.<div><img class="confluence-embedded-image confluence-external-resource" src="http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-click-stack.png" data-image-src="http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-click-stack.png"></div></li><li>Also, when your script contains compilation errors, the error messages are clickable too.<div><img class="confluence-embedded-image confluence-external-resource" src="http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-click-comp-error.png" data-image-src="http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-click-comp-error.png"></div></li></ul><p>Back on the visualization of the results in the script output area, a fun system was added to let you customize how certain results are rendered. When you execute a script returning a map of Jazz musicians, you may see something like this in your console:</p><div><img class="confluence-embedded-image confluence-external-resource" src="http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-without-visu.png" data-image-src="http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-without-visu.png"></div><p>What you see here is the usual textual representation of a <code>Map</code>. But, what if we enabled custom visualization of certain results? The Swing console allows you to do just that. First of all, you have to ensure that the visualization option is ticked: <code>View -> Visualize Script Results</code> — for the record, all settings of the Groovy Console are stored and remembered thanks to the Preference API. There are a few result visualizations built-in: if the script returns a <code>java.awt.Image</code>, a <code>javax.swing.Icon</code>, or a <code>java.awt.Component</code> with no parent, the object is displayed instead of its <code>toString()</code> representation. Otherwise, everything else is still just represented as text. Now, create the following Groovy script in <code>~/.groovy/OutputTransforms.groovy</code>:</p><p> </p><pre><strong>import</strong> javax.swing.* transforms << { result -> <strong>if</strong> (result <strong>instanceof</strong> Map) { <strong>def</strong> table = <strong>new</strong> JTable( result.collect{ k, v -< [k, v?.inspect()] <strong>as</strong> Object[] } <strong>as</strong> Object[][], ['Key', 'Value'] <strong>as</strong> Object[]) table.preferredViewportSize = table.preferredSize <strong>return</strong> <strong>new</strong> JScrollPane(table) } } </pre><p>The Groovy Swing console will execute that script on startup, injecting a <code>transforms</code> list in the binding of the script, so that you can add your own script results representations. In our case, we transform the <code>Map</code> into a nice-looking Swing <code>JTable</code>. And we're now able to visualize maps in a friendly and attractive fashion, as the screenshot below shows:<img class="confluence-embedded-image confluence-external-resource" src="http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-with-visu.png" data-image-src="http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-with-visu.png"></p><p>The Swing console is obviously not to be confused with a real full-blown IDE, but for daily scripting tasks, the console is a handy tool in your toolbox.</p><h2>Metaprogramming enhancements</h2><p>What makes Groovy a dynamic language is its Meta-Object Protocol and its concept of metaclasses which represent the runtime behavior of your classes and instances. In Groovy 1.6, we continue improving this dynamic runtime system, bringing several new capabilities into the mix.</p><h3>Per instance metaclass even for POJOs</h3><p>So far, Groovy POGOs (Plain Old Groovy Objects) could have a per-instance metaclass, but POJOs could only have one metaclass for all instances (ie. a per-class metaclass). This is now not the case anymore, as POJOs can have a per-instance metaclass too. Also, setting the metaclass property to null will restore the default metaclass.</p><h3>ExpandoMetaClass DSL</h3><p>Initially developed under the <a href="http://grails.org/">Grails</a> umbrella and integrated back into Groovy 1.5, ExpandoMetaClass is a very handy way for changing the runtime behavior of your objects and classes, instead of writing full-blow <code>MetaClass</code> classes. Each time, we want to add / change several properties or methods of an existing type, there is too much of a repetition of <code>Type.metaClass.xxx</code>. Take for example this extract of a <a href="http://groovy.dzone.com/news/domain-specific-language-unit-">Unit manipulation DSL</a> dealing with operator overloading:</p><pre>Number.metaClass.multiply = { Amount amount -> amount.times(delegate) } Number.metaClass.div = { Amount amount -> amount.inverse().times(delegate) } Amount.metaClass.div = { Number factor -> delegate.divide(factor) } Amount.metaClass.div = { Amount factor -> delegate.divide(factor) } Amount.metaClass.multiply = { Number factor -> delegate.times(factor) } Amount.metaClass.power = { Number factor -> delegate.pow(factor) } Amount.metaClass.negative = { -> delegate.opposite() } </pre><p>The repetition, here, looks obvious. But with the ExpandoMetaClass DSL, we can streamline the code by regrouping the operators per type:</p><pre>Number.metaClass { multiply { Amount amount -> amount.times(delegate) } div { Amount amount -> amount.inverse().times(delegate) } } Amount.metaClass { div << { Number factor -> delegate.divide(factor) } div << { Amount factor -> delegate.divide(factor) } multiply { Number factor -> delegate.times(factor) } power { Number factor -> delegate.pow(factor) } negative { -> delegate.opposite() } } </pre><p>A <code>metaClass()</code> method takes a closure as single argument, containing the various definitions of the methods and properties, instead of repeating the <code>Type.metaClass</code> on each line. When there is just one method of a given name, use the pattern <code>methodName { /* closure */ }</code>, but when there are several, you should use the append operator and follow the patten <code>methodName << { /* closure */ }</code>. Static methods can also be added through this mechanism, so instead of the classical approach:</p><pre>// add a fqn() method to Class to get the fully // qualified name of the class (ie. simply Class#getName) Class.metaClass.static.fqn = { delegate.name } <strong>assert</strong> String.fqn() == "java.lang.String" </pre><p>You can now do:</p><pre>Class.metaClass { 'static' { fqn { delegate.name } } } </pre><p>Note here that you have to quote the <code>static</code> keyword, to avoid this construct to look like a static initializer. For one off method addition, the classical approach is obviously more concise, but when you have several methods to add, the EMC DSL makes sense.</p><p>The usual approach for adding properties to existing classes through ExpandoMetaClass is to add a getter and a setter as methods. For instance, say you want to add a method that counts the number of words in a text file, you could try this:</p><pre>File.metaClass.getWordCount = { delegate.text.split(/\w/).size() } <strong>new</strong> File('myFile.txt').wordCount </pre><p>When there is some logic inside the getter, this is certainly the best approach, but when you just want to have new properties holding simple values, through the ExpandoMetaClass DSL, it is possible to define them. In the following example, a <code>lastAccessed</code> property is added to a <code>Car</code> class — each instance will have its property. Whenever a method is called on that car, this property is updated with a newer timestamp.</p><pre><strong>class</strong> Car { <strong>void</strong> turnOn() {} <strong>void</strong> drive() {} <strong>void</strong> turnOff() {} } Car.metaClass { lastAccessed = <strong>null</strong> invokeMethod = { String name, args -> <strong>def</strong> metaMethod = delegate.metaClass.getMetaMethod(name, args) <strong>if</strong> (metaMethod) { delegate.lastAccessed = <strong>new</strong> Date() metaMethod.doMethodInvoke(delegate, args) } <strong>else</strong> { <strong>throw new</strong> MissingMethodException(name, delegate.class, args) } } } <strong>def</strong> car = new Car() println "Last accessed: ${car.lastAccessed ?: 'Never'}" car.turnOn() println "Last accessed: ${car.lastAccessed ?: 'Never'}" car.drive() sleep 1000 println "Last accessed: ${car.lastAccessed ?: 'Never'}" sleep 1000 car.turnOff() println "Last accessed: ${car.lastAccessed ?: 'Never'}" </pre><p>In our example, in the DSL, we access that property through the <code>delegate</code> of the closure, with <code>delegate.lastAccessed = new Date()</code>. And we intercept any method call thanks to <code>invokeMethod()</code>, delegating to the original method for the call, and throwing an exception in case the method doesn't exist. Later on, you can see by executing this script that <code>lastAccessed</code> is updated as soon as we call a method on our instance.</p><h3>Runtime mixins</h3><p>Last metaprogramming feature we'll cover today: runtime mixins. <code>@Mixin</code> allowed you to mixin new behavior to classes you owned and were designing. But you could not mixin anything to types you didn't own. Runtime mixins propose to fill that gap by letting you add a mixin on any type at runtime. If we think again about our example of vehicles with some mixed-in capabilities, if we didn't <em>own</em> James Bond's vehicle and give it some diving ability, we could use this mechanism:</p><pre>// provided by a third-party <strong>interface</strong> Vehicle { String getName() } // provided by a third-party <strong>class</strong> JamesBondVehicle <strong>implements</strong> Vehicle { String getName() { "James Bond's vehicle" } } JamesBondVehicle.mixin DivingAbility, FlyingAbility <strong>assert new</strong> JamesBondVehicle().fly() == "I'm the James Bond's vehicle and I fly!" <strong>assert new</strong> JamesBondVehicle().dive() == "I'm the James Bond's vehicle and I dive!" </pre><p>One or more mixins can be passed as argument to the static <code>mixin()</code> method added by Groovy on <code>Class</code>.</p><h2>JSR-223 Groovy Scripting Engine</h2><p>Before Groovy 1.6, if you wanted to integrate Groovy in your Java projects through JSR-223 / <code>javax.script.*</code>, you had to download a Groovy script engine implementation from java.net, and put the JAR in your classpath. This additional step wasn't very developer friendly, requiring some additional work — the JAR wasn't even provided in the Groovy distribution. Thankfully, 1.6 comes with an implementation of the <code>javax.script.*</code> APIs.</p><p>Below, you'll find an example evaluating Groovy expressions (the code is in Groovy, but it's straightforward to convert it back to Java):</p><pre><strong>import</strong> javax.script.* <strong>def</strong> manager = <strong>new</strong> ScriptEngineManager() <strong>def</strong> engine = manager.getEngineByName("groovy") <strong>assert</strong> engine.evaluate("2 + 3") == 5 </pre><p>Please note that the <code>javax.script.*</code> APIs are available only on Java 6.</p><h2>JMX Builder</h2><p>Originiating as an <a href="http://code.google.com/p/groovy-jmx-builder/">external Open-Source project</a> hosted on Google Code, JMX Builder has been integrated in Groovy 1.6, to simplify the life of developers needing to interact or expose JMX services. JMX Builder features:</p><ul><li>Domain Specific Language (DSL) for JMX API using Builder pattern</li><li>Simplified JMX API's programmability</li><li>Declaratively expose Java/Groovy objects as JMX managed MBeans</li><li>Support class-embedded or explicit descriptors</li><li>Inherent support for JMX's event model</li><li>Seamlessly create JMX event broadcasters</li><li>Attach event listeners as inline closures</li><li>Use Groovy's dynamic nature to easily react to JMX events notifications</li><li>Provides a flexible registration policy for MBean</li><li>No special interfaces or class path restrictions</li><li>Shields developer from complexity of JMX API</li><li>Exposes attribute, constructors, operations, parameters, and notifications</li><li>Simplifies the creation of connector servers and connector clients</li><li>Support for exporting JMX timers</li></ul><p>You can find <a href="http://groovy.codehaus.org/Groovy+JmxBuilder">more information on JMX Builder</a> and its very extensive coverage of the JMX system. Lots of examples will show you how to create a JMX connector server or client, how to easily export POGOs as JMX managed beans, how to listen to JMX events, and much more.</p><h2>Improved OSGi support</h2><p>The Groovy jar files are released with correct OSGi metadata, so they can be loaded as a bundle into any OSGi compliant container, such as Eclipse Equinox or Apache Felix. You can find <a href="http://docs.codehaus.org/display/GROOVY/OSGi+and+Groovy">more information on how to use Groovy and OSGi</a> on the Groovy project website. This tutorial will explain how to:</p><ul><li>Load Groovy as an OSGi service</li><li>Write a Groovy OSGi service</li><li>Incude the Groovy JAR within a bundle</li><li>Plublish a service written in Groovy</li><li>Consume a service from Groovy</li><li>Troubleshoot in case you're encountering any problem along the way</li></ul><p>You may also be interested in, for instance, how you can <a href="http://hamletdarcy.blogspot.com/2008/12/beginners-guide-to-osgi-on-desktop.html">use different versions of Groovy in your application</a>, thanks to OSGi.</p><h2>Summary</h2><p>Groovy continues its march towards the goal of <strong>simplifying the life of developers</strong>, providing various new features and improvements in this new release: AST transformations reducing dramatically the number of lines of code to express certain concerns and patterns and opening the language to developers for further extension, several <strong>metaprogramming enhancements to streamline your code</strong> and let you write <strong>more expressive business rules</strong>, and <strong>support for common enterprise APIs</strong> such as Java 6's scripting APIs, JMX management system, or OSGi's programming model. All of this is done obviously <strong>without compromising on the seamless integration with Java</strong>, and furthermore, with a <strong>level of performance way higher than previous releases</strong>.</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