
- •brief contents
- •contents
- •foreword
- •preface
- •acknowledgments
- •about this book
- •Roadmap
- •Code conventions and downloads
- •Author Online
- •About the author
- •about the cover illustration
- •1 Why add Groovy to Java?
- •1.1 Issues with Java
- •1.1.1 Is static typing a bug or a feature?
- •1.1.2 Methods must be in a class, even if you don’t need or want one
- •1.1.3 Java is overly verbose
- •1.1.4 Groovy makes testing Java much easier
- •1.1.5 Groovy tools simplify your build
- •1.2 Groovy features that help Java
- •1.3 Java use cases and how Groovy helps
- •1.3.1 Spring framework support for Groovy
- •1.3.2 Simplified database access
- •1.3.3 Building and accessing web services
- •1.3.4 Web application enhancements
- •1.4 Summary
- •2 Groovy by example
- •2.1 Hello, Groovy
- •2.2 Accessing Google Chart Tools
- •2.2.1 Assembling the URL with query string
- •2.2.2 Transmitting the URL
- •2.2.3 Creating a UI with SwingBuilder
- •2.3 Groovy Baseball
- •2.3.1 Database data and Plain Old Groovy Objects
- •2.3.2 Parsing XML
- •2.3.3 HTML builders and groovlets
- •2.4 Summary
- •3 Code-level integration
- •3.1 Integrating Java with other languages
- •3.2 Executing Groovy scripts from Java
- •3.2.1 Using JSR223 scripting for the Java Platform API
- •3.2.2 Working with the Groovy Eval class
- •3.2.3 Working with the GroovyShell class
- •3.2.4 Calling Groovy from Java the easy way
- •3.2.5 Calling Java from Groovy
- •3.3 Summary
- •4 Using Groovy features in Java
- •4.1 Treating POJOs like POGOs
- •4.2 Implementing operator overloading in Java
- •4.3 Making Java library classes better: the Groovy JDK
- •4.4 Cool AST transformations
- •4.4.1 Delegating to contained objects
- •4.4.2 Creating immutable objects
- •4.4.3 Creating singletons
- •4.5 Working with XML
- •4.6 Working with JSON data
- •4.7 Summary
- •5 Build processes
- •5.1 The build challenge
- •5.2 The Java approach, part 1: Ant
- •5.3 Making Ant Groovy
- •5.3.1 The <groovy> Ant task
- •5.3.2 The <groovyc> Ant task
- •5.3.3 Writing your build in Groovy with AntBuilder
- •5.3.4 Custom build scripts with Gant
- •5.3.5 Ant summary
- •5.4 The Java approach, part 2: Maven
- •5.4.2 The GMaven project
- •5.4.3 Maven summary
- •5.5 Grapes and @Grab
- •5.6 The Gradle build system
- •5.6.1 Basic Gradle builds
- •5.6.2 Interesting configurations
- •5.7 Summary
- •6 Testing Groovy and Java projects
- •6.1 Working with JUnit
- •6.1.1 A Java test for the Groovy implementation
- •6.1.2 A Groovy test for the Java implementation
- •6.1.3 A GroovyTestCase test for a Java implementation
- •6.2 Testing scripts written in Groovy
- •6.2.1 Useful subclasses of GroovyTestCase: GroovyShellTestCase
- •6.2.2 Useful subclasses of GroovyTestCase: GroovyLogTestCase
- •6.3 Testing classes in isolation
- •6.3.1 Coerced closures
- •6.3.2 The Expando class
- •6.3.3 StubFor and MockFor
- •6.4 The future of testing: Spock
- •6.4.1 The Search for Spock
- •6.4.2 Test well, and prosper
- •6.4.4 The trouble with tribbles
- •6.4.5 Other Spock capabilities
- •6.5 Summary
- •7 The Spring framework
- •7.1 A Spring application
- •7.2 Refreshable beans
- •7.3 Spring AOP with Groovy beans
- •7.4 Inline scripted beans
- •7.5 Groovy with JavaConfig
- •7.6 Building beans with the Grails BeanBuilder
- •7.7 Summary
- •8 Database access
- •8.1 The Java approach, part 1: JDBC
- •8.2 The Groovy approach, part 1: groovy.sql.Sql
- •8.3 The Java approach, part 2: Hibernate and JPA
- •8.4 The Groovy approach, part 2: Groovy and GORM
- •8.4.1 Groovy simplifications
- •8.5 Groovy and NoSQL databases
- •8.5.1 Populating Groovy vampires
- •8.5.2 Querying and mapping MongoDB data
- •8.6 Summary
- •9 RESTful web services
- •9.1 The REST architecture
- •9.3 Implementing JAX-RS with Groovy
- •9.4 RESTful Clients
- •9.5 Hypermedia
- •9.5.1 A simple example: Rotten Tomatoes
- •9.5.2 Adding transitional links
- •9.5.3 Adding structural links
- •9.5.4 Using a JsonBuilder to control the output
- •9.6 Other Groovy approaches
- •9.6.1 Groovlets
- •9.6.2 Ratpack
- •9.6.3 Grails and REST
- •9.7 Summary
- •10 Building and testing web applications
- •10.1 Groovy servlets and ServletCategory
- •10.2 Easy server-side development with groovlets
- •10.2.1 A “Hello, World!” groovlet
- •10.2.2 Implicit variables in groovlets
- •10.3.2 Integration testing with Gradle
- •10.3.3 Automating Jetty in the Gradle build
- •10.4 Grails: the Groovy “killer app”
- •10.4.1 The quest for the holy Grails
- •10.5 Summary
- •A.1 Installing a JDK
- •A.2 Installing Groovy
- •A.3 Testing your installation
- •A.4 IDE support
- •A.5 Installing other projects in the Groovy ecosystem
- •B.1 Scripts and the traditional example
- •B.2 Variables, numbers, and strings
- •B.2.1 Numbers
- •B.2.2 Strings and Groovy strings
- •B.3 Plain Old Groovy Objects
- •B.4 Collections
- •B.4.1 Ranges
- •B.4.2 Lists
- •B.4.3 Maps
- •B.5 Closures
- •B.6 Loops and conditionals
- •B.6.1 Loops
- •B.6.2 Conditionals
- •B.6.3 Elvis
- •B.6.4 Safe de-reference
- •B.7 File I/O
- •B.8.1 Parsing and slurping XML
- •B.8.2 Generating XML
- •B.8.3 Validation
- •B.9 JSON support
- •B.9.1 Slurping JSON
- •B.9.2 Building JSON
- •index
- •Symbols

Closures |
309 |
to the get method being its new value. This is convenient, but it means that if you accidentally misspell a key when trying to retrieve it you don’t get an error; instead, you wind up adding it. That’s not true when using the single-argument version of get.
Finally, when you iterate over a map using a closure, the number of dummy arguments determines how the map is accessed. Using two arguments means that the map is accessed as keys and values:
String keys1 = '' List<Integer> values1 = [] both.each { key,val ->
keys1 += '|' + key values1 << val
}
The each iterator has two dummy variables, so the first represents the key and the second the value. This closure appends the keys to a string, separated by vertical bars. The values are added to a list.
Alternatively, using a single argument assigns each entry to the specified argument, or it if none:
String keys2 = '' List<Integer> values2 = [] both.each { entry ->
keys2 += '|' + entry.key values2 << entry.value
}
Because a single dummy argument was used in the closure, I need to access its key and value properties (equivalent to invoking the getKey and getValue methods, as usual) to do the same operation as in the previous example.
Both mechanisms produce the same results:
assert keys1 == keys2 assert values1 == values2
Throughout this section I’ve used closures in examples without defining what they are. That’s the subject of the next section.
B.5 Closures
Like many developers, I started out in the procedural world. I started my career as a research scientist, studying unsteady aerodynamics and acoustics. Most of that involved numerically solving partial differential equations.
That meant that unless I wanted to write all my own libraries, I had to adopt Fortran as my professional language of choice.11 My first assignment in my first job was to take a 3000-line program my boss had written in Fortran IV12 and add functionality to
11The fact that I seriously considered writing those libraries in a different language anyway was yet another sign I was in the wrong profession.
12Shudder. Holy arithmetic-if statements, Batman. The nightmares have stopped, but it took a while.
www.it-ebooks.info

310 |
APPENDIX B Groovy by feature |
it. The best part was that the original program had only two subroutines in it: one that was about 25 lines long, and the other 2975. Needless to say, I learned refactoring long before I knew the actual term.
I rapidly learned what at the time were considered good development practices, meaning that I wrote structured programs that used existing libraries as much as possible. It was only in the mid-90s, when I first learned Java, that I was introduced to object-oriented programming.
That’s when I first encountered what influential blogger Steve Yegge has since referred to as the subjugation of verbs in the kingdom of the nouns.13 In most OO languages, methods (verbs) can only exist as part of nouns (classes). Java certainly works that way. Even static methods that don’t require objects still have to be defined inside classes somewhere.
The first language I learned that changed all that was JavaScript, which is an object-based language rather than object-oriented. In JavaScript, even the classes are functions. Then, because the methods in the classes are also functions, you wind up with functions operating inside of functions, possibly passing around references to still other functions, and suddenly everything gets confusing and difficult. Closures in JavaScript are confusing not because functions are difficult, but because a closure includes the environment in which it executes. A closure may have references to variables declared outside of it, and in JavaScript it’s easy to get lost determining the values.
I had no idea how simple closures could be until I encountered Groovy.14 In Groovy, it’s easy enough to treat a closure as a block of code, but it’s always clear where the nonlocal variables are evaluated because there’s no confusion about the current object.
CLOSURES In practice, a closure is a block of code along with its execution environment.
In Groovy, the term closure is used broadly to refer to blocks of code, even if they don’t contain explicit references to external variables. Closures feel like methods and can be invoked that way. Consider this trivial example, which returns whatever it’s sent:
def echo = { it }
assert 'Hello' == echo('Hello') assert 'Hello' == echo.call('Hello')
The echo reference is assigned to the block of code (a closure) delimited by curly braces. The closure contains a variable whose default name is it, whose value is supplied when the closure is invoked. If you think of the variable like a method parameter, you’ve got the basic idea.
The closure can be invoked in one of two ways: either by using the reference as though it’s a method call, or by explicitly invoking the call method on it. Because the
13“Execution in the Kingdom of Nouns,” at http://mng.bz/E4MB
14Others can say the same about Ruby or other JVM languages. This is my history, though.
www.it-ebooks.info