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="warning" data-macro-parameters="title=Warning" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e3dhcm5pbmc6dGl0bGU9V2FybmluZ30&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="RICH_TEXT"><tr><td class="wysiwyg-macro-body"> <p>This page was created to report about the changes in syntax when we switched to a new parser back in 2004. So some of the points below are not necessarily representative of what Groovy supports nowadays. Please take the notes below with a grain of salt!</p></td></tr></table> <p>Here is a checklist of changes you'll need to make to a Groovy classic codebase to ensure compatibility with the new Groovy JSR syntax.</p> <h2>Safe navigation</h2> <p>In Classic Groovy we used to use this syntax</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 Person = { String name } y = null println "${y->name}" // -> was the optional gpath operator with Classic Groovy syntax </pre></td></tr></table> <p>Instead of using the arrow operator for safe navigation to avoid NullPointerException, we're now using the ?. operator</p> <p>Now in the JSR we use this syntax</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 Person = { String name } def y = null println "${y?.name}" // Now, ?. is the optional gpath operator the new Groovy JSR </pre></td></tr></table> <h2>Parameter separator in the closure syntax</h2> <p>This allows us to use one single token for the separator between the closure in Classic Groovy we used to use this syntax</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> cl = {a| ...} cl = {|a| ...} </pre></td></tr></table> <p>Now in the JSR we use this syntax</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 cl = {a -> ...} </pre></td></tr></table> <p>This allows us to use one single token for the separator between the closure parameters and the code in in the closure which works with arbitrarily complex parameter list expressions and default values. e.g.</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 cl = {String x = "hey", int y = a|b -> println "Values are $x and $y"} collection.each {int item -> println item} </pre></td></tr></table> <h2>Property keyword</h2> <ul> <li>property keyword has been replaced with an annotation <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 Foo { property foo } </pre></td></tr></table> <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 Foo { @Property foo } </pre></td></tr></table></li> </ul> <h2>Introduction of the 'def' keyword</h2> <ul> <li>local variable declarations and fields currently need to be specified with 'def', a modifier, and/or a type. e.g. <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 foo() { int x = 123 y = 456 // classic } def foo() { int x = 123 def y = 456 // JSR } class Foo { telson // classic int sharna } class Foo { def telson // JSR int sharna } </pre></td></tr></table> (Syntactically, the new keyword 'def' acts for methods as a modifier like 'public'.)</li> </ul> <p>For Scripts (as opposed to explicitely declared classes) the syntax is not changed, i.e. variable declarations without 'def' are still allowed, because those variables are automatically created in the script binding if they don't already exist.</p> <h2>Introduction of the 'as' keyword</h2> <ul> <li>We can change types of objects with using the 'as' keyword,<br /> e.g. <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 d0 = new Date(2005-1900, 5-1, 7) // in classic Groovy or Java println d0 def d1 = [2005-1900, 5-1, 8] as Date // since jsr-01 println d1 Date d2 = [2005-1900, 5-1, 9] as Date // since jsr-01 println d2 Date d3 = [2005-1900, 5-1, 10] // since jsr-01 println d3 // def n0 = new int[] { 1, 3, 5, 6 } // Not work. This style is not supported since groovy-1.0-jsr-01. def n1 = [ 1, 3, 5, 7 ] as int[] println n1.class println n1.size() println n1.length println n1[0] println n1[-1] // int[] n2 = [ 2, 4, 6, 8,10 ] as int[] // work int[] n2 = [ 2, 4, 6, 8, 10 ] // work println n2.class println n2.size() println n2.length println n2[0] println n2[-1] // String[] n3 = [ "a", "ab", "abc", "abcd", "abcde", "abcdef" ] as String[] // work String[] n3 = [ "a", "ab", "abc", "abcd", "abcde", "abcdef" ] // work println n3.class println n3.size() println n3.length println n3[0] println n3[-1] </pre></td></tr></table></li> </ul> <h2>Default access level of class members</h2> <p>The default access level for members of Groovy classes has changed from "public" to "protected"</p> <p>Classic Groovy</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 Foo { readMe_a; readMe_b } xyz = new Foo(readMe_a:"Hello",readMe_b:"World") println xyz.readMe_a println xyz.readMe_b </pre></td></tr></table> <p>Now in JSR Groovy</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 Foo { public readMe_a; def readMe_b //def is now required because of the "def keyword" change mentioned earlier } xyz = new Foo(readMe_a:"Hello",readMe_b:"World") println xyz.readMe_a println xyz.readMe_b //errors in JSR Groovy </pre></td></tr></table> <h2>Array creation</h2> <ul> <li>no special array syntax. To make the language much cleaner, we now have a single syntax to work with lists and arrays in the JSR. Also note that we can now easily coerce from any collection or array to any array type</li> </ul> <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> // classic args = new String[] { "a", "b" } // JSR String[] args = [ "a", "b" ] def x = [1, 2, 3] as int[] long[] y = x </pre></td></tr></table> <ul> <li><strong>Be careful:</strong> we don't support native multi-dimensional array creation right now.</li> </ul> <h2>float and double notation</h2> <ul> <li>float and double literals cannot start with dot. So</li> </ul> <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> x = .123 // classic def x = 0.123 // JSR </pre></td></tr></table> <p>This is to avoid ambiguity with things like ranges (1..2) and so forth</p> <h2>Explicit method pointer syntax</h2> <p>In classic Groovy you could access method pointers automatically if there was no java bean property of the given method name.</p> <p>e.g.</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> // classic methodPointer = System.out.println methodPointer("Hello World") </pre></td></tr></table> <p>This often caused confusion; as folks would use a property access to find something and get a method by accident (e.g. typo) and get confused. So now we make getting a method pointer explicit 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> // JSR def methodPointer = System.out.&println methodPointer("Hello World") def foo = ... def p = foo.&bar // lets call the bar method on the foo object p(1, 2, 3) </pre></td></tr></table> <h2>No 'do ... while()' syntax as yet.</h2> <p>Due to ambiguity, we've not yet added support for do .. while to Groovy</p> <h2>'No Dumb Expression' rule</h2> <ul> <li>no dumb expression rule, so we will catch dumb expressions (where a carriage return has broken the script). e.g. <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 foo() { def x = 1 +5 // dumb expression! return 8 } </pre></td></tr></table></li> </ul> <h2>Markup and builders</h2> <ul> <li>markup / builders will change a little, but the classic syntax still applies. Not sure of the new syntax, but we'll have some kinda start/stop syntax to denote a markup block. Maybe a keyword, like</li> </ul> <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> markup (builder) { // same stuff as before goes here } // or something like this builder.{ // same stuff as before goes here } </pre></td></tr></table> <h2>Strings and GStrings</h2> <ul> <li>single and double quote strings can only span one line; for multiple lines use triple quotes</li> </ul> <ul> <li>heredocs removal - they are kinda ugly anyway <img class="emoticon emoticon-smile" data-emoticon-name="smile" border="0" src="/s/en_GB/3278/15/_/images/icons/emoticons/smile.png" alt="(smile)" title="(smile)" />. If you want to use them, just use treble quote instead</li> </ul> <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 foo = """ this is a very long string on many lines """ </pre></td></tr></table> <ul> <li>escaping of $ inside GStrings must use \$</li> </ul> <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> println 'amount is $100' // same as println "amount is \$100" </pre></td></tr></table> <ul> <li>A new string definition is also supported which is escaping friendly, and thus particularly friendly for regex notation:</li> </ul> <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> if ('abc' =~ /.../) {} if ('abc' ==~ /.../) {} 'abc'.eachMatch(/.../) {} ['a','b','c'].grep(/a/) switch('abc'){ case ~/.../ : whatever } assert 'EUOUAE'.matches(/^[aeiou]*$/) assert 'EUOUAE' ==~ /^[aeiou]*$/ assert 'football'.replaceAll(/foo/, "Bar") == 'Bartball' </pre></td></tr></table> <h2>Assertions</h2> <ul> <li>assert uses comma instead of colon to delimit the two parameter form of assertion statement</li> </ul> <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> assert 0 <= value : "Must be non-negative" // classic </pre></td></tr></table> <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> assert 0 <= value , "Must be non-negative" // JSR </pre></td></tr></table> <h2>return/break/continue semantics in closures</h2> <p><strong>NOT YET IMPLEMENTED</strong></p> <ul> <li>return/break/continue to behave inside closures like these statements work in other blocks (such as the block on a for() or while() loop. More details here</li> </ul> <h2>Integer division</h2> <p>Previously, in Groovy Classic, we used the backward slash as the integer division operator. This operator being confusing with escaping sequences was removed. So instead of \ please use the intdiv() method.</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> int result = 5 \ 3 // classic </pre></td></tr></table> <p>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> int result = 5.intdiv(3) // JSR </pre></td></tr></table> <h2>Exclusive range</h2> <p>The operator for creating ranges with the upper bound excluded from the range has changed.</p> <p>Instead of:</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> range = 0...10 </pre></td></tr></table> <p>The syntax is now:</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 range = 0..<10 </pre></td></tr></table>
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