Groovy Java companion – introduction
Some of us come to Java from scripting languages like Python, Ruby or Perl.
Almost everything in Java is fascinating but small things make us irritated. Java is a verbose programming language and writing programs similar in functionality to scripts is cumbersome. Dealing with stuff like XML, json, even Strings is not so handy. Things which should be straightforward are awkward. Thank God there are plenty of third-party libraries like Apache Commons, Guava, Gson which makes our life feasible. Try to rewrite a program from Perl to Java. Imagine a source code with a lot of regular expressions, which are first class components in Perl. Then it comes to you that you have to escape double quotes and syntax is a little different and you can’t just copy, paste. You can imagine that most of the regexes would require changes and thus the whole process leads to debugging regular expressions and this is like a nightmare. So Java developers in such cases would say I wish I would write in Python … I would write it quicker and source code would be up to 50% shorter, but I have to write it unfortunately in Java …
Another case, Scala new modern JVM language has recently been becoming more and more popular. It’s target is to be Java replacement. Frequently I have heard when developers say: have you seen what it can do with collections? this is much more concise language than Java, and it supports Actors model which simplifies dealing with concurrency. This is awesome! But there are some disadvantages Scala is quite demanding, difficult to learn, the learning curve is pretty steep. Moreover there are problems with dependencies, you have to stick to a certain version. The language is so difficult that also frequently I hear from Java developers, Scala yes, I tried it, but I gave up it was too difficult.
Yet another case some developers before implementing a big project build a kind of prototype to check if their assumptions while designing work. And they don’t have enough time to implement the prototype in verbose Java. They could of course implement it in Python but it would be nice to have the possibility to reuse an already done job and invested time …
Now comes Groovy modern dynamic JVM language which was not designed like Scala to be a Java replacement but to be Java Companion. That makes a world of difference. Groovy also is not a Scala competitor. It fulfils places where Java lacks and makes possible easy scripting, and rapid development feasible. The learning curve is not very steep, at the beginning just change java file extension to groovy and that is all.
Compared to Java Groovy the amount of boilerplate code has been minimised as possible. You don’t need to write a semicolon at the end of every line. In Java you have to write getters/setters. Of course modern IDE could generate it for you, but it clutters the code. In Groovy those are generated at bytecode level, you don’t have to write them manually.
One of its strong points is the ability to create so-called Domain Specific Language – DSL. The most important and well-known DSL is Gradle, a build automation tool. it is created in Groovy. This is a perfect solution because in stark contrast to Java where the base of DSL is xml. DSL in xml is cumbersome to maintain, develop and debug. When DSL is written in Groovy adding new functionality it is just writing normal code. This is far more natural and easy. It may surprise you but Gradle contains plug-ins for Scala and JavaScript.
Groovy contain many things which we miss in Java, like easy building and parsing xml, json. A feature which already contains Scala and will be the most important change in Java 8, lambdas called another way closures. Closures are something like a pointer to method and they are first class Groovy citizens. Closure can be defined as method put between braces and then for instance passed as method argument. They can be called lazily. Closures makes working with collection very straightforward.
def list = ['a','b','c','d'] def upperCase = list.collect { it.toUpperCase() } assert list instanceof ArrayList assert upperCase == ["A", "B", "C", "D"]
This small code snippet shows the power of Groovy. The first list is Java ArrayList but created and initialized with the smaller amount of code. Then method collect which iterates over whole collection calling closure on every item. Closure is between braces, it means the current collection element so this code iterates over ArrayList and calls method toUpperCase() on every element. Simple, powerful, elegant.
Groovy provides means like scripting language to deal easily with files: creating, transforming, traversing directory structure. It makes templating a very easy task. Even running and chaining external processes are natural to code.
If you need to have scripting language inside your Java application, Groovy provides a means for it. Because it uses among others means of reflection, you can use Groovy as an advanced debugging tool in a very sophisticated environment. These capabilities make Groovy an ideal language for writing Unit Tests for Java classes, Groovy can run your class private methods …
And so on and so on. I prepared a project on GitHub to present some interesting Groovy capabilities: https://github.com/zsokolowski/Groovy-TJUG
Groovy is dynamic. It means that types are inferred from context. Thanks to def keyword, flow typing is possible it means that you can change a type of variable just by assigning other type. Dynamic also means that you could any behaviour of class in runtime. Due to fact that methods and variables are called indirectly through so-called Meta Object Protocol you can add, change methods and properties to class, even in the runtime. For instance Groovy 2.1.3 adds 250 methods to well-known Java String class, and you could add them more and they can do whatever you can imagine. Of course nothing is for free so this dynamic behaviour has two drawbacks. First is that errors are seen at runtime, second is performance penalty.
First one doesn’t create such a huge problem because modern IDE like my favourite IntelliJ Idea, helps a lot just by syntax colouring. If it is not enough, special annotations could change Groovy behaviour. Namely @TypeCheck and @CompileStatic. The former forces Groovy to check variable, method names and returned types so it eliminates typos, and forces code to be consistently written. But there is always a cost, this time you we lose power of meta programming i.e. features like adding methods in runtime. Code generated this way although statically checked will be the same as dynamically checked. Only compiler became grumpy. Program performance will be the same as in pure dynamic mode. If you need performance similar to Java and you use older than Java 7, second annotation apart from statically type checking causes Groovy to produce static code. Code generated this way will be similar to produced by Java. Although you still benefit from more concise source code. For newer Java there is one more alternative.
Java 7 introduced new bytecode instruction called invokeDynamic. This changes rule of game, because up to Java 7, code was called or by reflection or proxy classes. Even using so-called cache-site which accelerates performance, results are substantially worse (slower) than Java. Nowadays thanks to method handles and invokeDynamic which calls special method stub which in turn calls destination method whole process is much faster. This functionality will be heavily used in Java 8. Yes, Java 8 will be much more dynamic than predecessors.
Dynamic nature of Groovy gives us completely new opportunities to create software, new excellent tools, and gives us something what is so-called “Groovy magic”. I strongly encourage you to get acquainted with that magic.
Where Groovy is used? There is number of well-known frameworks done in Groovy, lets enumerate a few of them:
- Grails – rapid website development framework
- Gradle – mentioned above build automation tool, currently it is used even by Android project
- Spock – powerful testing framework, similar to Mockito
- GPars – concurrency library which uses Actor model
And many others, Groovy became second language for Spring framework.