Why Groovy?
It's been about a year since I joined my company's DevOps team and one of the main tools we use is Jenkins which gets along great with Groovy. I mostly use Groovy for orchestrating pipelines and automating some boring tasks.
Groovy is a powerful language for the Java platform, it integrates smoothly with any Java program. It's also a great scripting language with its powerful and easy to learn syntax.
[Groovy is] aimed at improving developer productivity thanks to a concise, familiar and easy to learn
syntax. It integrates smoothly with any Java program, and immediately delivers to your application
powerful features, including scripting capabilities, Domain-Specific Language authoring,
runtime and compile-time meta-programming and functional programming.
So here are 10 features that I've learned in the past year that made me love Groovy:
1. Simplicity
Coming from a Java back-end development team, learning Groovy was a breeze for me. It is build on top of Java standard libraries, providing extra features. Most of them make programming much simpler.
1.1 Declaring Lists/Maps
Groovy is an optionally typed language, you can use the def
keyword to declare variables. For example declaring lists or maps is as simple as:
def myList = []
def myMap = [:]
1.2 Iterating over Lists/Maps
And iterating over them is incredibly easy and readable using Closures:
myList.each {element ->
println element
}
myMap.each {entry ->
println "User: $entry.user | Email: $entry.email"
}
2. String Interpolation
[String] Interpolation is the act of replacing a placeholder in the string with its value upon evaluation of the string.
In Groovy, placeholders are surrounded by ${}
or prefixed with $
for dotted expressions.
In the previous snippet we can see an example of string interpolation. But here is another one:
try{
throw new Exception()
}catch(Exception e){
println "Error during operation. Cause: ${e}"
}
3. Casting
Groovy makes casting very easy and readable with the as
operator. To use this operand the casted class must implement the asType()
method. This already happens for standard classes like lists, enumerators, etc.
For example:
enum Employee {
MIKE,
HANNA
}
String name = "JOHN"
try{
name as Employee
}catch(Exception e){
println "Could not find employee ${name}. Cause: ${e}"
}
4. Json to Classes
I work a lot with Web Services with Json responses so inevitably I have had to map responses to Groovy classes. This comes out of the box with Groovy and it's extremely easy, just pass a Json through the class constructor.
String response = '{name:"John", position: "Developer", age: 32}'
// Json response to map
def employeeMap = new JsonSlurper().parseText(response)
// Consider an Employee class with the attributes name, position and age
Employee employee = new Employee(employeeMap)
That's it. We just built an employee object from a Json string.
The other way around is just as simple:
def json = JsonOutput.toJson(employee)
// json == '{name:"John", position: "Developer", age: 32}'
5. Assertions
Groovy has the same assert
statement as Java, but way more powerful - hence it's name - Power Assertions.
The difference being its output in case the assertions resolves to false
. For example:
def contacts = ['John', 'Anna']
assert contacts.isEmpty()
//Output:
//ERROR org.codehaus.groovy.runtime.powerassert.PowerAssetionError:
//assert contacts.isEmpty()
// | |
// | false
// [John, Anna]
This allows you to very easily understand what has made the assertion fail.
6. Defining variables
Groovy is optionally type, this means that you can define a variable with its type or simply use the keyword def
. This applies as well when declaring List or Maps, their types are optional. For example:
String name
int age
def address
List friends = ['John', 'Anna']
Map family = ['Mother':'Mary', 'Father':'Joseph']
def getFamilyMember("Mother"){ ... }
For those of you who know Javascript, this is similar to the keyword var
.
This gives you incredible flexibility, however be cautious when using it. It might make it harder on your team or someone else using your code to read it and understand what is expected as input or output.
7. Hashing
If you've ever used Java, you probably know how verbose it is to hash a string - unless you're using a third-party library.
Groovy 2.5 brings us some useful methods to the String
class. Calculating hashes is as simple as calling a method on a String. Groovy makes it simple:
def password = "thisIsMyPassword"
def md5 = password.md5()
def sha256 = password.sha256()
//For other algorithms use digest() method
def sha1 = password.digest('SHA-1')
...
8. Operators
Groovy supports the most common operators found in other languages. But that's not enough the are some more interesting operators Groovy provides. Here are a few:
Elvis operator
This is a shorter version of the ternary operator. This is very useful, for example, when the condition could evaluate to null.
// Instead of this
def user = person.name ? person.name : 'Guest'
// Use this
def user = person.name ?: 'Guest'
Safe navigation operator
Another operator that can be used to check if a variable is null is the Safe Navigation Operator.
def user = person?.name
// user == null
Use this operator when you want to avoid NullPointerException
s. In case the object you're accessing is null, this operator will return a null
instead of throwing a NullPointerException
.
Spread Operator
The spread operator (.*
) is used to execute an action on all items of a Collection, instead of using a loop or a closure as we've seen before. For example:
def numbers = [1,2,3,4,5,6]
*numbers // == [1,2,3,4,5,6]
def people = [
new Person(name: 'John', age: '25'),
new Person(name: 'Anna', age: '21')
]
def friends = people*.name // friends = ['John', 'Anna']
9. Traits
Traits are a structural construct of the language which allows:
composition of behaviors
runtime implementation of interfaces
behavior overriding
compatibility with static type checking/compilation
I like to think of traits as interfaces where you can actually implements methods. It's very useful when you have a very complex and structured application and you want to keep things clean.
It's definetly something I've missed in the early Java.
Here's an example:
trait Sociable {
void greet() { println "Hello!" }
}
class Person implements Sociable {}
Person p = new Person()
p.greet() // Hello!
10. Regular Expressions
Groovy natively supports regular expressions and it's quite simple. It has 3 operators for regular expressions:
-
~
this is the pattern operator, its the simple way to create an instance ofjava.util.regex.Pattern
:
def pattern = ~"^abc{2}\d"
// pattern instanceof Pattern == true
-
=~
this is the find operator which will look for a pattern in a string and returns aMatcher
:
def pattern = ~"abc{2}\d"
def found = "abcc5" =~ pattern
// found instanceof Matcher == true
- and finally the match operator
==~
which returnstrue
if the string is a strict match of the regex:
def found = "abcc5" ==~ pattern
// found == true
Conclusion
Groovy feels like a breath of fresh air if you've been programming in Java, or other OOP languages, for years.
It makes things so much easier and simple and way less verbose. Plus the extra features like scripting and Domain Specific Language capabilities, push Groovy to a new level and gives it this new fresh look that's missing for older languages.
I hope you found this article interesting and let me know in the comments below if you have any experience with Groovy and how do you use it. :)
Top comments (11)
What is your view on Kotlin compared to Groovy?
(Background: In my team we have an active debate going on for the last months about switching to Kotlin. We have been using Groovy for some years but feel that the language is slowly 'dying' and getting less interest in favour of Kotlin.)
Groovy has been evolving for years and Groovy 3.0.0 will be released with lots of new features this year, so Groovy is not 'dying' and will not be die.
Thank you for the great work you're doing to groovy 3.0, I still believe that groovy should become one day fully static compile in order to live longer, maybe it's in the roadmap of 4.0, and it's ok to deprecate things that prevent that from happening.
Hey Hidde,
I think they're both very interesting languages, and of course, once a new language comes along its "competitors" start losing some track in the community.
In the end I believe they will coexist, but be narrowed down to their specific purposes/applications. They both have their own strengths.
What are you guys using Groovy for? In your place I would start new projects in Kotlin, just to see how it goes, but not migrate old ones.
Yes, we have no trouble using Groovy for multiple projects. It is a great language.
Whad I personally miss the most in Groovy (versus Kotlin) is the type safety of all kinds of closures. And nullability.
For the more scripting side of things, Groovy might remain a better option than Kotlin in some cases.
Thanks a lot for share with us
I started using groovy in 2011, all these features were there, so why we should use it in 2019, does it have anything new? I would rather use kotlin now
Great article José Coelho.
Good tips for whom's starting with Groovy.
Other interesting article would be Groovy vs Java performance comparison.
and yep! Groovy 3.0 is here
groovy-lang.org/releasenotes/groov...
This is why Micronaut comes in hand where you can still use Groovy and GORM but get higher speeds. At least that's what I understood from reading about Micronaut, never actually tested it myself.
Thanks for sharing this.