Groovy in Action
Groovy in Action
DIERK KÖNIG
WITH ANDREW GLOVER, PAUL KING
GUILLAUME LAFORGE, AND JON SKEET
MANNING
Greenwich
(74° w. long.)
For online information and ordering of this and other Manning books, please go to
www.manning.com. The publisher offers discounts on this book when ordered in quantity.
For more information, please contact:
Special Sales Department
Manning Publications Co.
Cherokee Station
PO Box 20386
Fax: (609) 877-8256
New York, NY 10021
email:
©2007 by Manning Publications Co. All rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted,
in any form or by means electronic, mechanical, photocopying, or otherwise, without
prior written permission of the publisher.
Many of the designations used by manufacturers and sellers to distinguish their products
are claimed as trademarks. Where those designations appear in the book, and Manning
Publications was aware of a trademark claim, the designations have been printed in initial
caps or all caps.
Recognizing the importance of preserving what has been written, it is Manning’s policy
to have the books they publish printed on acid-free paper, and we exert our best efforts
to that end.
Manning Publications Co.
Cherokee Station
Copyeditor: Benjamin Berg
PO Box 20386
Typesetter: Denis Dalinnik
New York, NY 10021
Cover designer: Leslie Haimes
ISBN 1-932394-84-2
Printed in the United States of America
1 2 3 4 5 6 7 8 9 10 – MAL – 10 09 08 07 06
To the love of my life
—D.K.
brief contents
1
PART 1
PART 2
■
Your way to Groovy
1
THE GROOVY LANGUAGE ...................................... 27
2
■
Overture: The Groovy basics
29
3
■
The simple Groovy datatypes
55
4
■
The collective Groovy datatypes
5
■
Working with closures
6
■
Groovy control structures
7
■
Dynamic object orientation, Groovy style
93
122
153
174
AROUND THE GROOVY LIBRARY ........................ 227
8
■
Working with builders
9
■
Working with the GDK
10
■
Database programming with Groovy
11
■
Integrating Groovy
360
12
■
Working with XML
401
vii
229
277
323
viii
BRIEF CONTENTS
PART 3
EVERYDAY GROOVY ............................................ 451
13
■
Tips and tricks
453
14
■
Unit testing with Groovy
15
■
Groovy on Windows 546
16
■
Seeing the Grails light
appendix A
■
Installation and documentation
appendix B
■
Groovy language info 610
appendix C
■
GDK API quick reference
appendix D
■
Cheat sheets
631
503
572
613
606
contents
foreword xix
preface xx
acknowledgments xxiii
about this book xxv
about the authors xxix
about the title xxxii
about the cover illustration
1
xxxiii
Your way to Groovy 1
1.1
The Groovy story
3
What is Groovy? 4 Playing nicely with Java: seamless
integration 4 Power in your code: a feature-rich language
Community-driven but corporate-backed 9
■
■
1.2
What Groovy can do for you
10
Groovy for Java professionals 10 Groovy for script
programmers 11 Groovy for pragmatic programmers,
extremos, and agilists 12
■
■
1.3
Running Groovy
13
Using groovysh for “Hello World” 14 Using
groovyConsole 17 Using groovy 18
■
■
ix
6
x
CONTENTS
1.4
Compiling and running Groovy
19
Compiling Groovy with groovyc 19 Running a compiled
Groovy script with Java 20 Compiling and running
with Ant 21
■
■
1.5
Groovy IDE and editor support
22
IntelliJ IDEA plug-in 23 Eclipse plug-in 24
Groovy support in other editors 24
■
1.6
Summary
25
PART 1 THE GROOVY LANGUAGE ..................................... 27
2
Overture: The Groovy basics 29
2.1
General code appearance
30
Commenting Groovy code 30 Comparing Groovy and Java
syntax 31 Beauty through brevity 32
■
■
2.2
Probing the language with assertions
2.3
Groovy at a glance
33
36
Declaring classes 36 Using scripts 37 GroovyBeans 38
Handling text 39 Numbers are objects 40 Using lists,
maps, and ranges 41 Code as objects: closures 43
Groovy control structures 46
■
■
■
■
■
2.4
Groovy’s place in the Java environment 47
My class is your class 47
The Groovy lifecycle 50
2.5
3
Summary
■
GDK: the Groovy library
49
53
The simple Groovy datatypes 55
3.1
Objects, objects everywhere
56
Java’s type system—primitives and references 56
Groovy’s answer—everything’s an object 57
Interoperating with Java—automatic boxing and unboxing
No intermediate unboxing 60
3.2
The concept of optional typing
Assigning types
3.3
61
■
Overriding operators
59
61
Static versus dynamic typing
62
63
Overview of overridable operators 63 Overridden operators in
action 65 Making coercion work for you 67
■
■
CONTENTS
3.4
Working with strings 69
Varieties of string literals 69
From Java to Groovy 74
3.5
■
Working with GStrings
72
Working with regular expressions 76
Specifying patterns in string literals 78 Applying patterns 81
Patterns in action 82 Patterns and performance 85
Patterns for classification 86
■
■
3.6
Working with numbers 87
Coercion with numeric operators
GDK methods for numbers 90
3.7
4
Summary
87
91
The collective Groovy datatypes 93
4.1
Working with ranges 94
Specifying ranges 95
Ranges in action 98
4.2
Working with lists
■
Ranges are objects
97
100
Specifying lists 100 Using list operators 101
Using list methods 104 Lists in action 109
■
■
4.3
Working with maps 111
Specifying maps 111
Maps in action 117
4.4
■
Using map operators
Notes on Groovy collections
113
119
Understanding concurrent modification 119
Distinguishing between copy and modify semantics
4.5
5
Summary
120
121
Working with closures 122
5.1
A gentle introduction to closures 123
5.2
The case for closures
Using iterators
5.3
125
125
■
Handling resources 127
Declaring closures 130
The simple declaration 130 Using assignments for
declaration 131 Referring to methods as closures 131
Comparing the available options 133
■
■
xi
xii
CONTENTS
5.4
Using closures
135
Calling a closure
5.5
135
More closure methods
■
Understanding scoping
137
141
The simple variable scope 142 The general closure scope
Scoping at work: the classic accumulator test 146
143
■
5.6
Returning from closures 148
5.7
Support for design patterns
149
Relationship to the Visitor pattern 149 Relationship to the
Builder pattern 150 Relationship to other patterns 151
■
■
5.8
6
Summary
151
Groovy control structures 153
6.1
The Groovy truth
154
Evaluating Boolean tests
Boolean tests 156
6.2
154
■
Assignments within
Conditional execution structures
158
The humble if statement 158 The conditional ?:
operator 159 The switch statement 160
Sanity checking with assertions 163
■
■
6.3
Looping
167
Looping with while
6.4
167
■
Looping with for
Exiting blocks and methods
170
Normal termination: return/break/continue
Exceptions: throw/try-catch-finally 171
6.5
7
Summary
168
170
172
Dynamic object orientation, Groovy style 174
7.1
Defining classes and scripts
175
Defining fields and local variables 176 Methods and
parameters 180 Safe dereferencing with the ?. operator
Constructors 185
■
■
7.2
Organizing classes and scripts
188
File to class relationship 188 Organizing classes in
packages 190 Further classpath considerations 194
■
■
7.3
Advanced OO features 195
Using inheritance 195
Multimethods 197
■
Using interfaces
196
184
CONTENTS
7.4
Working with GroovyBeans 199
Declaring beans 200 Working with beans
Using bean methods for any object 205
Fields, accessors, maps, and Expando 206
■
7.5
xiii
Using power features
201
207
Querying objects with GPaths 208 Injecting the
spread operator 212 Mix-in categories with
the use keyword 213
■
■
7.6
Meta programming in Groovy 216
Understanding the MetaClass concept 216 Method invocation
and interception 218 Method interception in action 220
■
■
7.7
Summary
224
PART 2 AROUND THE GROOVY LIBRARY ........................... 227
8
Working with builders 229
8.1
Learning by example—using a builder
8.2
Building object trees with NodeBuilder 234
231
NodeBuilder in action—a closer look at builder code 235
Understanding the builder concept 237 Smart building
with logic 237
■
8.3
Working with MarkupBuilder 239
Building XML
8.4
240
■
Building HTML
Task automation with AntBuilder
241
243
From Ant scripts to Groovy scripts 243 How AntBuilder
works 245 Smart automation scripts with logic 246
■
■
8.5
Easy GUIs with SwingBuilder
247
Reading a password with SwingBuilder 248 Creating Swing
widgets 250 Arranging your widgets 254 Referring to
widgets 257 Using Swing actions 260 Using
models 262 Putting it all together 264
■
■
■
■
8.6
Creating your own builder 271
Subclassing BuilderSupport 272
The DebugBuilder example 274
8.7
Summary
276
■
■
xiv
CONTENTS
9
Working with the GDK
9.1
277
Working with Objects 278
Interactive objects 279 Convenient Object methods
Iterative Object methods 288
■
9.2
285
Working with files and I/O 291
Traversing the filesystem 294 Reading from input
sources 295 Writing to output destinations 297
Filters and conversions 298 Streaming serialized
objects 300
■
■
■
9.3
Working with threads and processes 301
Groovy multithreading 302
Integrating external processes
9.4
Working with templates
304
309
Understanding the template format 309 Templates in
action 310 Advanced template issues 312
■
■
9.5
Working with Groovlets 314
Starting with “hello world” 314
Templating Groovlets 319
9.6
10
Summary
■
The Groovlet binding
316
321
Database programming with Groovy 323
10.1
Basic database operations
325
Setting up for database access 325 Executing SQL 329
Fetching data 334 Putting it all together 338
■
■
10.2
DataSets for SQL without SQL
Using DataSet operations
database views 344
10.3
341
Organizing database work
■
340
DataSets on
347
Architectural overview 347 Specifying the application
behavior 349 Implementing the infrastructure 350
Using a transparent domain model 355 Implementing the
application layer 355
■
■
■
10.4
Groovy and ORM
10.5
Summary
358
357
xv
CONTENTS
11
Integrating Groovy 360
11.1
11.2
Getting ready to integrate
361
Integrating appropriately
■
362
Setting up dependencies
363
Evaluating expressions and scripts
with GroovyShell 365
Starting simply 365 Passing parameters within a
binding 367 Generating dynamic classes at runtime 369
Parsing scripts 370 Running scripts or classes 371
Further parameterization of GroovyShell 372
■
■
■
11.3
Using the Groovy script engine 376
Setting up the engine 376 Running scripts 377
Defining a different resource connector 377
■
11.4
Working with the GroovyClassLoader
378
Parsing and loading Groovy classes 378 The chicken and egg
dependency problem 380 Providing a custom resource
loader 384 Playing it safe in a secured sandbox 385
■
■
■
11.5
Spring integration
389
Wiring GroovyBeans
Inline scripts 392
11.6
390
■
Refreshable beans
Riding Mustang and JSR-223
392
393
Introducing JSR-223 393 The script engine manager
and its script engines 395 Compilable and invocable
script engines 396
■
■
12
11.7
Choosing an integration mechanism 398
11.8
Summary
399
Working with XML 401
12.1
Reading XML documents 402
Working with a DOM parser 403 Reading with a Groovy
parser 408 Reading with a SAX parser 414
Reading with a StAX parser 416
■
■
12.2
Processing XML
417
In-place processing 418 Streaming processing 421
Combining with XPath 426
■
xvi
CONTENTS
12.3
Distributed processing with XML
434
An overview of web services 435 Reading RSS and
ATOM 435 Using a REST-based API 437
Using XML-RPC 441 Applying SOAP 444
■
■
■
12.4
Summary
449
PART 3 EVERYDAY GROOVY ........................................... 451
13
Tips and tricks 453
13.1
Things to remember
454
Equality versus identity 454 Using parentheses wisely 455
Returning from methods and closures 456 Calling methods in
builder code 457 Qualifying access to “this” 459
Considering number types 460 Leveraging Ant 461
Scripts are classes but different 464
■
■
■
■
13.2
Useful snippets 467
Shuffling a collection 467 Scrambling text with regular
expressions 468 Console progress bar 468
Self-commenting single-steps 470
Advanced GString usage 471
■
■
13.3
Using groovy on the command line 472
Evaluating a command-line script 473 Using print and line
options 474 Using the listen mode 475
In-place editing from the command line 476
■
■
13.4
Writing automation scripts
476
Supporting command-line options consistently 477 Expanding
the classpath with RootLoader 481 Scheduling scripts
for execution 483
■
■
13.5
Example automation tasks
485
Scraping HTML pages 485 Automating web actions 487
Inspecting version control 489 Pragmatic code analysis 491
More points of interest 492
■
■
13.6
Laying out the workspace
493
IDE setup 494 Debugging 495
Refactoring 501
■
13.7
Summary
501
■
Profiling 500
CONTENTS
14
Unit testing with Groovy
14.1
Getting started
503
505
Writing tests is easy
introduction 506
505 GroovyTestCase: an
Working with GroovyTestCase
■
■
14.2
Unit-testing Groovy code 508
14.3
Unit-testing Java code 512
14.4
Organizing your tests 516
14.5
Advanced testing techniques
517
Testing made groovy 518 Stubbing and mocking
Using GroovyLogTestCase 525
■
14.6
IDE integration
508
520
527
Using GroovyTestSuite 527 Using AllTestSuite 529
Advanced IDE integration 531
■
14.7
14.8
Tools for Groovy testing
533
Code coverage with Groovy
533
Build automation
15
Summary
JUnit extensions 537
539
Build integration with Ant
with Maven 541
14.9
■
539
■
Build integration
544
Groovy on Windows 546
15.1
Downloading and installing Scriptom 547
15.2
Inside Scriptom
548
Introducing Jacob 548 Instantiating an ActiveX
component 550 Invoking methods 553
Accessing properties and return values 555
Event support 555
■
■
15.3
Real-world scenario: automating localization 558
Designing our document format 559 Designing the thesaurus
spreadsheet 560 Creating a Word document 562
Producing the final document 564
■
■
15.4
Further application automation
Accessing the Windows registry
automation system 568
566
565
■
Rolling out your own
xvii
xviii
CONTENTS
16
15.5
Where to get documentation
15.6
Summary
569
570
Seeing the Grails light 572
16.1
Setting the stage
573
Installing Grails
16.2
574
■
Getting your feet wet
Laying out the domain model 577
Thinking through the use cases 577
16.3
574
Implementing the domain model
■
Designing relations
578
579
Scaffolding domain classes 580 Scaffolding views and
controllers 581 Testing the web application 582
Completing the domain model 584
■
■
16.4
Customizing the views
585
Bootstrapping data 586 Working with Groovy Server
Pages 587 Working with tag libraries 590
■
■
16.5
Working with controllers and finder methods 592
16.6
Elaborating the model 595
16.7
Working with the session
16.8
Finishing up
600
Validating constraints
Farewell 604
appendix A
appendix B
appendix C
appendix D
596
601
■
Deploying the application
Installation and documentation 606
Groovy language info 610
GDK API quick reference 613
Cheat sheets 631
index 639
602
foreword
I first integrated Groovy into a project I was working on almost two years ago.
There is a long and rich history of using “scripting languages” as a flexible
glue to stitch together, in different ways, large modular components from a
variety of frameworks. Groovy is a particularly interesting language from this
tradition, because it doesn’t shy away from linguistic sophistication in the pursuit of concise programming, especially in the areas around XML, where it is
particularly strong. Groovy goes beyond the “glue” tradition of the scripting
world to being an effective implementation language in its own right. In fact,
while Groovy is often thought of and referred to as a scripting language, it
really is much more than that.
It is traditional for scripting languages to have an uneasy relationship with
the underlying linguistic system in which the frameworks are implemented. In
Groovy’s case, they have been able to leverage the underlying Java model to
get integration that is smooth and efficient. And because of the linguistic similarities between Java and Groovy, it is fairly painless for developers to shift
between programming in one environment and the other.
Groovy in Action by Dierk König and his coauthors is a clear and detailed
exposition of what is groovy about Groovy. I’m glad to have it on my bookshelf.
JAMES GOSLING
Creator of Java
Sun Microsystems, Inc.
xix
preface
Fundamental progress has to do with the reinterpretation of basic ideas.
—Alfred North Whitehead
In recent years, we have witnessed major improvements in software development with Java—and beyond. It’s easy to overlook these achievements when
you’re bogged down with daily development work. We work with elaborate
tool support, have all kinds of frameworks for various domains, and have discovered new agile ways of organizing software development in teams. Each of
these disciplines—tooling, frameworks, and methodology—has successfully
pushed its limits. We are still waiting for two other important aspects of software development to contribute to bringing our trade forward: personal skills
management and programming languages.
Language does matter. It determines how you perceive the world—and it
determines your world. Your programming language determines how you
think about software solutions and the way you think about the underlying
problems. Your knowledge of programming languages is key to your personal
skill portfolio as a software developer.
Source code is a means of communication: from you to the compiler, to
other team members, and then back to you. There is both a technical and a
human aspect in this communication. Classical programming languages focus
on the technical aspect and are optimized for performance and resource
xx
PREFACE
xxi
consumption. Other languages focus on the human aspect, trying to reveal the
programmer’s intent in the code as clearly as possible. Many attempts have been
made to bridge the two aspects, ranging from Literate Programming to Programming in Logic, none of which has taken the world by storm.
While Groovy is unlikely to dominate traditional languages, what distinguishes it from previous attempts is that it allows a smooth transition from
machine-centric to human-centric coding. It builds on the basic idea of the Java
platform with a new interpretation of code appearance. That means that on the
bytecode level, Groovy is Java, allowing a seamless mix-and-match of the two
languages. For example, unlike other projects that try to make scripting languages available on the Java platform, a literal string in Groovy is of the type
java.lang.String. You get the best of both worlds.
As a direct consequence, Groovy fully leverages the availability of frameworks,
with the Java standard library being the most important one. James Strachan
and Bob McWhirter founded the Groovy project in 2003, recognizing that application development in Java is characterized by using multiple frameworks and
gluing them together to form a product. They designed Groovy to streamline
exactly this kind of work.
At the same time, Richard Monson-Haefel met James, who introduced him
to Groovy. Richard immediately recognized Groovy’s potential and suggested
the submission of a Java Specification Request (JSR-241). To make a long story
short, this JSR passed “without a hitch,” as Richard puts it in his blog, thanks to
additional support from Geir Magnusson, Jr. and the foresight of the folks at
Sun Microsystems. They don’t see Groovy as Java’s rival but rather as a companion that attracts brilliant developers who might otherwise move to Ruby or
Python and thus away from the Java platform. Since the JSR has been accepted,
Groovy is the second standard language for the Java VM (besides the Java language itself).
The JSR process was the acid test for the Groovy community. It showed where
contributors were pushing in different directions and it imposed more structure
on the development than some were willing to accept. Development slowed
down in late 2004. This was when some key people stepped in and took the lead:
Guillaume Laforge and Jeremy Rayner organized what was later called GroovyOne. This led to a Groovy Language Specification (GLS), a Test Compatibility Kit
(TCK), and a new parser generated from a descriptive grammar specification.
They got the ball rolling again—a ball that has now become an avalanche.
From the beginning, it was clear that Groovy would need a book like Groovy
in Action to introduce newcomers to the language, provide comprehensive
xxii
PREFACE
documentation, and show what’s possible with Groovy in order to trigger the
reader’s curiosity and imagination.
John Wilson started this venture and passed the baton to Scott Stirling, who
in turn came across some contributions that I had made to the Groovy Wiki. He
quickly convinced me to join the book effort. By that time, I was downloading
every single bit of information that I could find about Groovy into my personal
knowledge base to have it available offline. I jotted down personal notes about
Groovy idioms that I found helpful. Putting all this into a book seemed natural,
even if it was only for my personal purposes.
Unfortunately, Scott had to resign and I was left alone for half a year, pushing
things forward as best I could. I was lucky enough to get support from Andrew
and Guillaume, both well-known Groovy experts. Andrew runs the Practically
Groovy online series and Guillaume is not only the Groovy project manager, he is
the heart and soul of Groovy. From day one of this book project, I was aware that
as I am not a native speaker, I would not be able to write a full-length book in
English without serious help. This was the initial reason for asking Dr. Paul King
and Jon Skeet to come on board. I could not have been luckier. It turned out that
they not only plowed tirelessly through every sentence in this book, leaving no
stone unturned, but clarified the book’s arguments, made the text more accessible, and corrected errors and weaknesses. They also suggested more compelling
examples, and, last but not least, contributed content. This book would never
have come to fruition without their diligent and mindful work.
Even though we will probably never see the day that Richard envisions “when
Groovy is used to control space flight and has solved world hunger,” I would be
pleased if Groovy, and this book, help to push our profession of software development one inch farther.
DIERK KÖNIG
acknowledgments
I’m very grateful for having had the opportunity to write this book. It has
helped me sharpen my programming skills in both Groovy and Java. Thanks
to my coauthors and editors, especially my development editor, Jackie Carter,
I also learned a great deal about writing. Most of all, I enjoyed working with
so many brilliant people!
I’m deeply indebted to our reviewing team: Jonas Trindler, Jochen Theodorou, Jeremy Rayner, Christopher DeBracy, Bob McWhirter, Sam Pullara,
John Stump, Graeme Rocher, Jeff Cunningham, Bas Vodde, Guillaume Alleon,
Doug Warren, Derek Lane, Scott Shaw, Norman Richards, Stuart Caborn, Glen
Smith, John Wilson, and Martin C. Martin. The “most observant reviewer”
award goes to Marc Guillemot!
Other friends helped with the book in one way or another: Denis Antonioli, Christian Bauer, Gerald Bauer, Tim Bray, Jesse Eichar, Benjamin Feiermann, James Gosling, Martin Huber, Stephan Huber, Andy Hunt, Vincent
Massol, Richard Monson-Haefel, Johannes Link, Rolf Pfenninger, Franck
Rasolo, Stefan Roock, Rene Schönfeldt, Tomi Schütz, Scott Stirling, Roman
Strobl, Frank Westphal, John Wilson, Dr. Russel Winder, all Groovy folks, as
well as participants in Manning’s Early Access Program.
Special thanks to Jochen Theodorou, the technical lead of the Groovy
project, and John Wilson, Groovy’s grandmaster of dynamic programming, for
always being available when we needed advice about Groovy’s inner workings.
xxiii
xxiv
ACKNOWLEDGMENTS
In addition, Jochen was the technical proofreader for the book, checking the
code one last time, just before the book went to press. Finally, very special thanks
to James Gosling for writing the foreword to Groovy in Action.
The book would never had made it to the shelves without the support and
guidance of everyone at Manning Publications, especially our publisher Marjan
Bace and our editor Jackie Carter. We would also like to thank the rest of the team
at Manning: Benjamin Berg, Denis Dalinnik, Gabriel Dobrescu, Dottie Marsico,
Mary Piergies, Iain Shigeoka, Hieu Ta, Tiffany Taylor, Karen Tegtmeyer, Katie
Tennant, Ron Tomich, Helen Trimes, Lianna Wlasiuk, and Megan Yockey.
My family, and especially my parents, have always supported me when times
were tough and—most importantly—encouraged me to pursue my ideas. Thank
you so much.