Why aren't there many Grails 3 tutorials out there

Introduction to Groovy (PDF)

What makes Groovy dynamic?

Now we come to the dynamic highlights of Groovy. If you call a method on a certain object of a certain type in Java, this call is permanently saved during compilation. In Groovy this is very different. Which method is to be called is only found out at runtime. This works because a method call is routed through a chain of framework classes. This means that you can influence at any time whether the call should be made at all or whether it is redirected to a completely different location. In this way, methods can still be linked to the call mechanism at runtime, even though they did not even exist at compile time. In order to properly understand dynamic programming with Groovy, one must inevitably deal with the internal processes. That would lead too far at this point. Nevertheless, a few possibilities should be presented how one can program dynamically.

One possibility is the expandos. It is a container for data (status) and methods (behavior) that can be "filled" at runtime.

def duck = new Expando () duck.name = 'Duffy' duck.fly = {length -> println "$ name flies about $ length km"} duck.fly (5)

Example 22: Expando

In the example you can see how the object is assigned an attribute with the value Duffy after instantiation. Methods are supplemented by setting a closure. Due to its properties, Expandos is very suitable as dummy objects for test purposes (stubs, mocks). But they also have some limitations. You cannot extend existing classes, implement interfaces or inherit from other classes.

As already indicated, Groovy is adding new functions to existing Java classes with the GDK. This mechanism can be implemented in Groovy in a similar way with the help of the keyword itself. To add a method to an existing class, this method must first be defined as a static method in a category class. The first parameter must always be of the type of the object on which the call is to be made later.

class StringCategory {static String swapCase (String self) {def sb = new StringBuffer () self.each {sb << (Character.isUpperCase (it as char)? Character.toLowerCase (it as char): Character.toUpperCase (it as char))} sb.toString ()}} use (StringCategory) {assert 'AlITTLEtEST' == 'aLittleTest'.swapCase ()}

Example 23: category

With you can attach the additional behavior to certain classes for a code block. However, this syntax makes using the categories very cumbersome. Since Groovy 1.1 there is a simpler variant with the ExpandoMetaClass. The difference between the two variants is that categories only ever attach additional functionality to objects in a certain thread, while the ExpandoMetaClass does this globally for all objects of a certain class. In the example below, the method is implemented a second time, this time for all objects of the String class.

String.metaClass.swapCase = {-> def sb = new StringBuffer () delegate.each {sb << (Character.isUpperCase (it as char)? Character.toLowerCase (it as char): Character.toUpperCase (it as char) )} sb.toString ()} assert tEsT == 'TeSt'.swapCase ()

Example 24: ExpandoMetaClass

The magic of ExpandoMetaClass doesn't end there. You can also define constructors, static methods, and so on, for example. With Groovy's method pointer syntax, a class can even borrow methods from another class, as the following example shows.

class Person {String name} class Dog {def bark () {'Bark'}} def lender = new Dog () Person.metaClass.imitateDog = lender. & bark def p = new Person () assert 'Bark' == p. imitateDog ()

Example 25: Borrowing Methods

The secret behind all these nice mechanisms is called the Meta Object Protocol (MOP). This protocol provides options for external modification of the behavior of objects. In Groovy, every class has a metaclass that you can use to get information about the class. For example, you can find out whether the class implements a certain method or offers a property. There are also so-called hook methods:

  • - Interception of all methods that are called on the class

  • - Interception of all failed method calls (if method does not exist)

  • - Interception of access to properties

  • - Interception of failed property accesses

With the help of these hook methods one can intervene in the call cycle, write interceptors (as in AOP), or redirect calls completely to dynamic implementations.

def someObject = 'Test' // print all the methods someObject.metaClass.methods.each {println it.name} // print all the properties someObject.metaClass.properties.each {println it.name}

Example 26: Meta information about classes

It even goes so far that you can dynamically add attributes or methods to Groovy objects (derived from GroovyObject) from Java and call them. However, in contrast to the internal use in Groovy, this way of working is quite cumbersome.

MOP is also the basis for creating Domain Specific Languages ​​(DSL). DSL is a language that offers a concise, easy-to-understand syntax for a special subject (domain) and thus achieves greater expressiveness. It is also easier for the technical experts to learn than a complex programming language, for example. In Groovy you can create so-called internal DSLs. These are embedded languages ​​that adopt language elements from the mother tongue.

A DSL implemented in Groovy benefits from the following points:

  • expressive and concise syntax

  • named parameters for method calls

  • Meta Object Protocol (dynamically add methods)

  • Operator overloading

  • Closures

  • Builder

An example of a simple DSL can be seen in the following example. The addition of physical quantities with different units is mainly based on the dynamic addition of methods to the Number (and) class, which convert the units, and the overloading of operators. As a reminder, when accessing properties you can write instead of directly.

println 4.km + 3 * 1000.m + 5.mile // -> 15.05 km

Example 27: Using a simple DSL

What is Groovy good for now?

Now it should be discussed when and for what it is worth using Groovy. Basically, Groovy can be used anywhere that Java is currently being programmed. As a great advantage, Groovy can throw the expressive and above all concise syntax and its dynamic abilities into the balance. This not only means that less source code has to be written, it also makes the code more readable and easier to maintain. Incidentally, less code also means fewer bugs, since studies have shown that the number of errors increases in relation to the number of lines of code.

Of course, dynamic capabilities in particular come at the expense of performance. Accordingly, Groovy is not recommended for critical applications. As a reminder, Java was considered very inperformant in its early days compared to C / C ++. The difference is now only minor and Groovy is also working on performance from release to release. And even if Groovy will certainly never be as powerful as a static programming language, the close integration with Java (same bytecode) means that performance-critical parts of the application can always be implemented in Java or even natively as a DLL (Java Native Interface).

Successful use of Groovy is reported again and again in lectures by the Groovy makers. A large American insurance company has now invested around 50,000 lines of code in a module for calculating risk. Other major users of Groovy are the French Ministry of Justice and the European Space Consortium (EADS).

Groovy's application possibilities range from selective use in Java programs, scripting at runtime, test support, prototypical implementations to complete applications and integration in Java EE projects. Due to the good integration between Groovy and Java, the use of Groovy is particularly suitable for small, specific problems in Java applications. Groovy shows its strengths when it comes to processing data, for example. The parsing of XML with subsequent GPath navigation can be solved much shorter, faster and more intuitively than with any Java API. When accessing files, Groovy relieves the developer of writing boiler plate code (e.g. closing files) and also supports him with many useful GDK methods. Other possible uses are access to databases, the development of user interfaces or the use of web services.

Another area of ​​application is scripting. Sub-items of this are the processing of recurring administrative tasks, the scheduling of tasks or the management of project infrastructures using build scripts (Ant). For Windows users there is a library called Scriptom, which, based on the Java COM Bridge (Jacob), allows remote control of Microsoft Office, for example. Not to be forgotten at this point are the so-called runtime macros. In OpenOffice, Groovy can be used as a macro language. It would also be conceivable to give the user the option of executing scripts in a running Java application, e.g. B. Entering functions in math software (f (x) = sin (x)). The Groovy code could just as easily come from databases or be downloaded from the Internet. In this way, the code base would be centralized and the user would always have the latest version without explicitly having to carry out local updates. There are several ways to run Groovy scripts at runtime. Since Java 6, a standardized interface for embedding script languages ​​has been included (JSR 223). Groovy itself offers three further options with the GroovyShell, the GroovyScriptingEngine and the GroovyClassLoader.

Testing is also child's play in Groovy and qualifies Groovy for test-driven development (TDD). In addition to the "assert" instructions built into the language (in contrast to Java, they cannot be switched off), Groovy provides a special JUnit TestCase with extended "assert" and "fail" methods. And just through the concise syntax, which has already been mentioned several times, the test code is shortened and, with regard to test documentation, more readable in the truest sense of the word. Thanks to its dynamic capabilities, it can also shine when creating stub and mock objects. Thanks to the MOP, substitutes can be created in Groovy without further libraries and thus test small units decoupled from their dependencies in real unit manner.

Last but not least, entire applications can of course be developed in Groovy. Groovy allows rapid and efficient development and is therefore ideal for creating prototypes. Due to the close integration in Java, these prototypes do not have to be completely re-implemented. Rather, you can easily build on it and develop new modules in Java or Groovy. Performance-critical parts in particular are more likely to be developed in Java. When it comes to integration in Java EE projects, Groovy is particularly suitable in two ways. On the one hand, you can see it as a kind of adhesive layer between the layers. With Groovy, a system can be configured programmatically (less XML), the user interface or the complete application can be adapted (customizing) and changes can be made to the running system very easily. The last point includes administrative interventions ala JMX, such as troubleshooting on the live system (admin console) and the import of hotfixes during runtime. This all works without the hassle of compiling and deploying. Anyone who has already developed EJB applications can tell a song about how much time is lost in the compile-deploy cycles. On the other hand, Groovy can also be used for business logic and, for example, outsource business rules via DSL (Domain Specific Language). DSLs are already very versatile and can serve as the foundation for the user interface, for tests and the actual business logic.

Conclusion

This article is intended to introduce you to Groovy. The power of this relatively young language can probably only be guessed at, since in this context, at best, the surface of the many useful features could be scratched. The possible uses are diverse and the entry hurdle is very low, especially for Java developers. Anyone who tries Groovy will likely fall in love quickly.

Another exciting topic is the Grails web framework, which is technically based on Groovy and many well-known Java APIs (Hibernate, Spring, ...). The principles of Grails include DRY (Don't repeat yourself) and easy familiarization through uniform guidelines (Convention over Configuration). A complete web application can be created in just a few steps. Productive, rapid development is promoted without annoying deployment cycles. Grails is therefore suitable, among other things, for rapid prototyping, but also for professional web applications.