• Home
  • About
  • Java Without the Boilerplate – Project Lombok

    July 26th, 2010

    Project Lombok is a very cool little Java library that aims (and succeeds) in removing boilerplate, meaningless, and uninteresting code from your Java objects. The basic idea is to replace things like getters and setters with simple annotations, and then let the Java compiler generate the necessary bytecode in the .class file so that tools such as Eclipse and the Java compiler have no idea what anything unusual happened. Lombok hooks into the compiler to make sure this happens correctly.

    First we’ll cover some Lombok basics and then show how it can be used with the Canoo RIA Suite (ULC) project and and view generators. This includes details on how to mix Lombok annotated objects with JPA annotations, which you might want to glance at before leaving!

    Update: You do not need ULC to work with Lombok. The two are separate projects.

    Lombok in Action
    So let’s see Lombok in action. Consider this Java class that includes a Lombok annotation:

    
    import lombok.Data;
    
    public @Data class Contact {
        private String name;
        private String email;
        private String primaryPhone;
    }
    

    OK, so there is an @Data annotation in there. So what? Well, to javac and tools (like Eclipse) this class has getters and setters for all three fields, an equals and hashcode implementation, and a toString method. Eclipse tools still give you autocomplete the Navigator shows the correct methods. Not only did you not have to write (or generate) the code yourself, but you don’t have to see that code when coming back in maintenance mode. The interesting bits of your class are no longer buried in the noise. Consider what this looks like without lombok:
    
    public @Data class Contact {
        private String name;
        private String email;
        private String primaryPhone;
    
        public String getName() {
            return name;
        }
       
        void setName(String name) {
          this.name = name;
        }
        
        public String getEmail() {
            return email;
        }
       
        void setEmail(String email) {
          this.email = email;
        }
    
        public String getPrimaryPhone() {
            return primaryPhone;
        }
       
        void setPrimaryPhone(String primaryPhone) {
          this.primaryPhone = primaryPhone;
        }
    
        @Override public String toString() {
            return "Contact(" + name + ", " 
                    + email + ", " 
                    + primaryPhone + ")";
        }
         
        @Override public boolean equals(Object o) {
            if (o == this) return true;
            if (o == null) return false;
            if (o.getClass() != this.getClass()) return false;
            Contact other = (Contact) o;
            if (name == null 
                    ? other.name != null 
                    : !name.equals(other.name)) return false;
            if (email == null 
                    ? other.email != null 
                    : !email.equals(other.email)) return false;
            if (primaryPhone == null 
                    ? other.primaryPhone != null 
                    : !primaryPhone.equals(other.primaryPhone)) return false;
            return true;
        }
         
        @Override public int hashCode() {
            final int PRIME = 31;
            int result = 1;
            result = (result*PRIME) + (name == null 
                    ? 0 
                    : name.hashCode());
            result = (result*PRIME) + (email == null 
                    ? 0 
                    : email.hashCode());
            result = (result*PRIME) + (primaryPhone == null 
                    ? 0 
                    : primaryPhone.hashCode());
            return result;
        }
    

    That’s a lot of code for something so simple. It doesn’t even fit in my browser margins without funky line breaks! Sure, IDEs can generate it for you. But what if something interesting is buried in the equals() method? Or perhaps a setter has a side-effect? You can’t easily see this with the reams of boilerplate typical of Java. With lombok, only the essentials are displayed, so the unique parts of the object will stand out to the future reader. And yes, even using @Data you are free to provide your own implementations for any of these methods.

    Richard Gabriel made this observation when comparing old programs (like MacPaint) to “modern” programs writen in langauges like Java:

    I’m always delighted by the light touch and stillness of early programming languages. Not much text; a lot gets done. Old programs read like quite conversations between a well-spoken research worker and a well-studied mechanical colleague, not as a debate with a compiler. Who’d have guessed sophistication brought such noise.

    Now, with Lombok, sophistication is finally taking the noise away, rather than adding to it.

    Just a couple important details before moving on to a Lombok example that uses Canoo’s RIA Suite

  • Lombok is compile time only. It does not need to be deployed with your app
  • Lombok works with javac and Eclipse. IntelliJ IDEA will not ‘see’ the added methods
  • lombok.jar contains an installer that configures your eclipse.ini file correctly. Be sure to run “java -jar lombok.jar” after you download it (especially for those on 64 bit Linux like me)
  • Lombok with Canoo RIA Suite
    The point of this was to make sure I could use Lombok on my next RIA Suite(aka ULC) project. It’s looks like I can, and you can too. To prove it, let’s generate a RIA Suite project, add a domain class using Lombok, generate the views, and run the application.

    Prerequisites

  • Install Eclipse for Java EE Developers. Make sure that you have for Java EE developers.
  • Install Canoo RIA Suite. Get your download and evaluation key from our customer portal.
  • Install Lombok. Download it and run “java -jar lombok.jar”.
  • Steps
    Here are the steps we’ll perform to get this thing working:

  • Generate a Project using ULC’s Project Generator in Eclipse
  • Add the lombok Jar to your project
  • Create a domain object called Contact and annotate it with @Data
  • Generate the views using ULC’s generate-beans-view in Eclipse
  • Run the app and behold a default, thin client, CRUD application
  • Generate the Project
    The ULC Application Development Guide contains a 10 page getting started tutorial that walks you through the process from starting at zero and going to a deployed RIA Suite application. Really, it is quite simple. You just need to add the Project Generator as an external tool in Eclipse. Although it is a bunch of screenshots, this is a common task for Eclipse users and little can go wrong.

    In Eclipse, click Run -> External Tools > Open External Tools Dialog… and point a new external tool to your “/addon/generators/build-setup.xml” from the RIA Suite install. Your window should look like this:

    0ToolConfiguration

    Now you’ll have the menu entry for Run -> External Tools -> ULC Project Generator, which you should click now. You’ll be prompted for a project name and whatnot, and a sample Contacts application will look like this:

    1GenerateProject

    The script runs and you now have a project on disk that can be run. Just click to File -> Import to import it, navigating to where it is on disk. Your import screen should look like this:

    2ImportProoject

    If it all goes well your project should be open and your Project Explorer should look like this:

    3ProjectView

    Add the Lombok Jar
    We need to add the lombok.jar to the Contacts project, add it to the build classpath, and click Refresh to make sure Eclipse is aware that something changed.

    Copy the lombok.jar to ./Contacts/lib/development directory in your project. Then edit the project properties (right click the Contacts project and select Properties), select the Java Build Path entry, and add lombok.jar as a Jar. Should look like this:

    4AddLibrary

    Create Domain Object
    Let’s add a domain object with JPA persistence to our project. A Contacts application must show a Contact, right? This looks about right:

    package org.sample.contacts.domain;
    
    import javax.persistence.*;
    import lombok.*;
    
    @Entity
    public @Data class Contact {
        
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        @Getter(AccessLevel.NONE)
        @Setter(AccessLevel.NONE)
        private Long id;
        private String name;
        private String email;
        private String primaryPhone;
    }
    

    Let me explain a few details… The class is marked @Entity so that JPA persistence works. The class will map to a Contact table in the database. The class is marked @Data so that lombok will weave in getters, setters, toString, equals, and hashcode methods. The @Id annotation on the “id” field marks that field as the primary key to JPA, and the @GeneratedValue means the field auto increments. I use the GenerationType.SEQUENCE strategy because I plan on deploying to Google App Engine, otherwise this parameter here is unneeded. Lastly, getters and setters are supressed on the id field by adding @Getter(AccessLevel.NONE) and @Setter(AccessLevel.NONE). If you don’t do this then the view-layer automation of Ria Suite is going to, by default, provide you with edit fields for the id, which you should not do.

    Generate the View Layer
    To generate the view layer, click Run -> External Tools -> “Contacts generate-beans-view”. This tool was installed for you by the Project Generator. Running it generates a simple Create-Read-Update-Delete (CRUD) interface with a table, buttons, and entry editor. You’ll see a couple new classes and property files in your application after you run the tool.

    Run application
    Last thing to do is run the app. Click Run -> Run History -> Contacts (again installed by the project generator), sit back, and behold an application.

    5DeployedApp

    That’s it!

    Next step is to deploy to Google App Engine using that Contacts-copy-to-GoogleApp tool that the generator installed, but that is a blog post (and task) for another day.

    Enjoy!


    Juggling with DLLs, WebStart and Maven

    May 6th, 2010

    Juggling with DLLs, WebStart and Maven

    Recently we were asked to implement a Drag & Drop mechanism between Microsoft Outlook and a Java based internet application. This necessitated our Java server having to communicate with COM objects on the client side. How do you do that?

    The good thing is that our application was built using UltraLightClient, so we had java on both the server and on the client side. And after some thinking, the steps seemed pretty clear, even if a tiny bit of juggling would be required. However, the juggle almost turned into a struggle when we encountered some unexpected pitfalls.

    In this blog I will give a quick sketch of our solution and point out some of the traps to be aware of.

    Step 1: Talking COM using JACOB

    In order to communicate with Microsoft programs from Java you need a Java COM Bridge.
    We were using JACOB and it was surprisingly easy to extract Outlook mails into Java objects.

    The idea:
    The following method extracts the selected outlook mails to a directory and returns the list of created files:

    [[code]]czo4NDU6XCINCnB1YmxpYyBMaXN0IGV4dHJhY3RNYWlscyhGaWxlIHRlbXBEaXIpIHsNCiAgICBMaXN0IG91dGxvb2tGaWxlcyA9IG57WyYqJl19ZXcgQXJyYXlMaXN0KCk7DQoNCiAgICBBY3RpdmVYQ29tcG9uZW50IGNvbXAgPSBuZXcgQWN0aXZlWENvbXBvbmVudChcXFwiT3V0bG9ve1smKiZdfWsuQXBwbGljYXRpb25cXFwiKTsNCiAgICBEaXNwYXRjaCBleHBsb3JlciA9IERpc3BhdGNoLmdldChjb21wLCBcXFwiQWN0aXZlRXhwbG9ye1smKiZdfWVyXFxcIikudG9EaXNwYXRjaCgpOw0KICAgIERpc3BhdGNoIHNlbGVjdGlvbiA9IERpc3BhdGNoLmdldChleHBsb3JlciwgXFxcIlNlbGVje1smKiZdfXRpb25cXFwiKS50b0Rpc3BhdGNoKCk7DQogICAgSW50ZWdlciBtYWlsQ291bnQgPSBEaXNwYXRjaC5nZXQoc2VsZWN0aW9uLCBcXFwiQ291e1smKiZdfW50XFxcIikuZ2V0SW50KCk7DQoNCiAgICBmb3IgKGludCBtYWlsSW5kZXggPSAxOyBtYWlsSW5kZXggPD0gbWFpbENvdW50OyBtYWlsSXtbJiomXX1uZGV4KyspIHsNCiAgICAgICAgRGlzcGF0Y2ggbWFpbEl0ZW0gPSBEaXNwYXRjaC5jYWxsKHNlbGVjdGlvbiwgXFxcIkl0ZW1cXFwiLCBuZXtbJiomXX13IFZhcmlhbnQobWFpbEluZGV4KSkudG9EaXNwYXRjaCgpOw0KICAgICAgICBWYXJpYW50IHN1YmplY3QgPSBEaXNwYXRjaC5nZXQoe1smKiZdfW1haWxJdGVtLCBcXFwiU3ViamVjdFxcXCIpOw0KDQogICAgICAgIEZpbGUgZW1haWxGaWxlID0gbmV3IEZpbGUodGVtcERpciwgc3ViamVje1smKiZdfXQudG9TdHJpbmcoKStcXFwiLm1zZ1xcXCIpOw0KICAgICAgICBEaXNwYXRjaC5jYWxsKG1haWxJdGVtLCBcXFwiU2F2ZUFzXFxcIiwgZW1haWxGaXtbJiomXX1sZS5nZXRQYXRoKCkpOw0KICAgICAgICBvdXRsb29rRmlsZXMuYWRkKGVtYWlsRmlsZSk7DQogICAgfQ0KDQogICAgcmV0dXJuIG91e1smKiZdfXRsb29rRmlsZXM7DQp9DQpcIjt7WyYqJl19[[/code]]

    The trap:
    Using the email subject as a file name is practical, but it can contain many weird characters which may not be supported when the files are created. We found out that JACOB has problems creating files containing even characters like “:” and “,”. Furthermore, no exception is thrown, although the file fails to be created completely.

    The solution:
    Replace potentially dangerous characters with something neutral using regular expressions:

    [[code]]czoxOTk6XCINCnB1YmxpYyBTdHJpbmcgZ2V0VmFsaWRGaWxlTmFtZShTdHJpbmcgcmF3U3RyaW5nKSB7DQogICAgUGF0dGVybiBpbnZ7WyYqJl19YWxpZENoYXJhY3RlcnMgPSBQYXR0ZXJuLmNvbXBpbGUoXFxcIlteQS1aYS16MC05XyB7fSshXVxcXCIpOw0KICAgIHJldHVybiBpbnZhbGl7WyYqJl19ZENoYXJhY3RlcnMubWF0Y2hlcihyYXdTdHJpbmcpLnJlcGxhY2VBbGwoXFxcIiBcXFwiKTsNCn0NClwiO3tbJiomXX0=[[/code]]

    To be on the safe side we were using a whitelist approach. We treat everything as invalid except for characters which are listed after the “^” character.

    Step 2: Shipping a DLL with Webstart

    JACOB can talk to Outlook because it comes with a DLL which has to be present in the classpath. This means we either have to ensure that all our users have this library installed (yikes!) or we ship it together with the application client using Java Webstart.

    The idea:
    We include the DLL in the jar file and sign it with a valid certificate. Then it can be referenced from the JNLP file that launches your web application:

    [[code]]czoxNzM6XCINClsuLi5dDQogICAgPCEtLSBBdHRlbnRpb246IFRoaXMgZG9lcyBub3Qgd29yayEhISAtLT4NCiAgICA8cmVzb3VyY2V7WyYqJl19cyBvcz1cXFwiV2luZG93c1xcXCI+DQogICAgICAgIDxuYXRpdmVsaWIgaHJlZj1cXFwibXktZGxsLmphclxcXCIgZG93bmxvYWQ9XFxcImxhenlcXFwiL3tbJiomXX0+DQogICAgPC9yZXNvdXJjZXM+DQpbLi4uXQ0KXCI7e1smKiZdfQ==[[/code]]

    The trap:
    We were using the optional parameter download=”lazy” to ensure that the library is only downloaded when it is really needed. The result was that it never got loaded at all(!) because we did not specify to which “part” the library belongs. This is another optional parameter which turns mandatory in combination with download=”lazy”.
    Unfortunately this little detail is not too well documented. The only hint found was this one (in german). It took me quite some time to find this critical information.

    The solution:
    Since the jar containing our DLL is really small we chose to use download=”eager” (which is the default anyway) instead of defining “parts” in our JNLP.

    [[code]]czoxNTU6XCINClsuLi5dDQogICAgPCEtLSBUaGlzIG9uZSBpcyBlYXNpZXIgYW5kIGl0IHdvcmtzISAtLT4NCiAgICA8cmVzb3VyY2V7WyYqJl19cyBvcz1cXFwiV2luZG93c1xcXCI+DQogICAgICAgIDxuYXRpdmVsaWIgaHJlZj1cXFwibXktZGxsLmphclxcXCIvPg0KICAgIDwvcmVzb3VyY2Vze1smKiZdfT4NClsuLi5dDQpcIjt7WyYqJl19[[/code]]

    Step 3: Using native lib references with the webstart-maven-plugin

    We already were using Maven as a build system and our client distribution is generated with the webstart-maven-plugin as follows:
    - We use a separate module with packaging type “pom” for the generation of the webstart client. Of course, this module is part of the multi module build for our application.
    - We provide a template for the JNLP file containing a parameter “$dependencies” which will be replaced by a list of the dependencies of the current module
    - At build time the dependencies will be signed and put into a zip file together with the JNLP file.
    - The zip file can be extracted to a java webstart server or, in our case, into a war file that will be deployed on a server.

    The idea:
    Since JACOB is available via Maven Central integration seemed pretty easy. We only have to generate the correct reference to the native library.

    The trap:
    Unfortunately the current version of the webstart-maven-plugin (1.0-alpha-2) does not support native libs (open issue). So we will need a workaround that wraps the jacob.dll into a jar file and generates the nativelib reference in our JNLP.

    The solution:
    Perform the following steps:
    - Change the packaging type for the module from “pom” to “jar”.
    - Configure the pom.xml to copy jacob.dll from the maven repository into the build directory of the module using the maven-dependency-plugin
    - Add the nativelib reference to the velocity template using the build artifact of the current module as a reference.

    [[code]]czo5OTk6XCINClsuLi5dDQogICAgPHBsdWdpbj4NCiAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm97WyYqJl19dXBJZD4NCiAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tZGVwZW5kZW5jeS1wbHVnaW48L2FydGlmYWN0SWQ+DQogICAgICAgIDxleHtbJiomXX1lY3V0aW9ucz4NCiAgICAgICAgICAgIDxleGVjdXRpb24+DQogICAgICAgICAgICAgICAgPHBoYXNlPmdlbmVyYXRlLXNvdXJjZXM8e1smKiZdfS9waGFzZT4NCiAgICAgICAgICAgICAgICA8Z29hbHM+DQogICAgICAgICAgICAgICAgICAgIDxnb2FsPmNvcHk8L2dvYWw+DQogICB7WyYqJl19ICAgICAgICAgICAgIDwvZ29hbHM+DQogICAgICAgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+DQogICAgICAgICAgICAgICAgICAgIHtbJiomXX08YXJ0aWZhY3RJdGVtcz4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxhcnRpZmFjdEl0ZW0+DQogICAgICAgICAgICAgICAgICAge1smKiZdfSAgICAgICAgIDxncm91cElkPm5ldC5zZi5qYWNvYi1wcm9qZWN0PC9ncm91cElkPg0KICAgICAgICAgICAgICAgICAgICAgICAgICB7WyYqJl19ICA8YXJ0aWZhY3RJZD5qYWNvYjwvYXJ0aWZhY3RJZD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dmVyc2lvbj4xLjE0LntbJiomXX0zPC92ZXJzaW9uPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0eXBlPmRsbDwvdHlwZT4NCiAgICAgICAgICAgICAgICAge1smKiZdfSAgICAgICAgICAgPGNsYXNzaWZpZXI+eDg2PC9jbGFzc2lmaWVyPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvdXRwdXR7WyYqJl19RGlyZWN0b3J5PiR7cHJvamVjdC5idWlsZC5vdXRwdXREaXJlY3Rvcnl9PC9vdXRwdXREaXJlY3Rvcnk+DQogICAgICAgICAgICAgIHtbJiomXX0gICAgICAgICAgPC9hcnRpZmFjdEl0ZW0+DQogICAgICAgICAgICAgICAgICAgIDwvYXJ0aWZhY3RJdGVtcz4NCiAgICAgICAgICAge1smKiZdfSAgICAgPC9jb25maWd1cmF0aW9uPg0KICAgICAgICAgICAgPC9leGVjdXRpb24+DQogICAgICAgIDwvZXhlY3V0aW9ucz4NCiAgICB7WyYqJl19PC9wbHVnaW4+DQpbLi4uXQ0KXCI7e1smKiZdfQ==[[/code]]

    [[code]]czoyNzA6XCINClsuLi5dDQogICAgPHJlc291cmNlcz4NCiAgICAgICAgPGoyc2UgdmVyc2lvbj1cXFwiMS41K1xcXCIgaW5pdGlhbC1oZWFwe1smKiZdfS1zaXplPVxcXCIyNTZNXFxcIiBtYXgtaGVhcC1zaXplPVxcXCI1MTJNXFxcIi8+DQogICAgICAgICRkZXBlbmRlbmNpZXMNCiAgICA8L3Jlc291cntbJiomXX1jZXM+DQogICAgPHJlc291cmNlcyBvcz1cXFwiV2luZG93c1xcXCI+DQogICAgICAgIDxuYXRpdmVsaWIgaHJlZj1cXFwiJHtwcm9qZWN0LmJ1e1smKiZdfWlsZC5maW5hbE5hbWV9LmphclxcXCIvPg0KICAgIDwvcmVzb3VyY2VzPg0KWy4uLl0NClwiO3tbJiomXX0=[[/code]]

    Summary:

    After successfully having avoided the traps (okay: by stepping into them and finding a way out again) we got an application with a pretty cool feature integrated seamlessly in our build process. Nice!


    Java Business RIA redefined!

    May 2nd, 2010

    The future belongs to Rich Internet Applications (RIA) – they are increasingly replacing the classical desktop application. And it is no wonder, as this latest generation of web applications offers a totally new kind of interactivity. Furthermore, RIAs spare your budget thanks to their operating system independence and the fact that they can be used without installation. According to the market research organization Forrester Research, RIA technology will be deployed in around 60% of all software development projects in the coming years.

    RIAbox_middle

    The disadvantage of most of today’s RIA frameworks is that they were developed for the optimization of web sites. They rapidly reach their limits, therefore, with complex business applications. Canoo Engineering’s Canoo RIA Suite with its modular design provides a remedy. It’s heart is ULC (UltraLightClient), a proven and stable component for the development of RIAs – optimized for the performance requirements of business applications. Thanks to the 100% java-based homogeneous programming model, ULC reduces the complexity of RIA projects to a minimum. RIAs developed with ULC score highly due to their low development and maintenance costs, and are more than a match for classical desktop applications in user-friendliness, functionality, attractiveness, robustness and performance.

    Since March 31, 2010, ULC Core is available as a Beta Release. The Canoo Ria Suite will be released officially just before Pentecost 2010. The advantages at a Glance:

    • Up to 50% reductions in development costs
    • Puts business functionality on to the web without quality losses
    • Lower operational costs thanks to server side maintenance and standardized technology
    • Maximum security thanks to standard conformity
    • Straightforward and rapid development due to uniform Java basis
    • Robust and scalable architecture
    • No longer time-consuming client-side deployment
    • Enables highly interactive and user friendly interfaces
    • No browser adaptation required
    • Optimal user productivity due to rapid response times
    • Lower project risk thanks to well engineered, tried and tested technology
    • Impressive prototypes in minimal time

    “We switched to ULC in the middle of a large software project, as we were not able to implement all the requirements with the technology we were using at the time. ULC then enabled us to at least double our productivity, in turn allowing the project to be completed on time.”

    Greg Hutchinson, Principal Developer of a large Canadian financial institution


    Maintenance Release UltraLightClient ‘08 Update 3

    July 2nd, 2009

    We are pleased to announce that the maintenance release UltraLightClient ‘08 Update 3 is now available for download.

    This is a maintenance release for UltraLightClient ‘08. Please see the release notes for a list of implemented feature requests and fixed problem reports.

    Please note: the UltraLightClient ‘08 license key is valid for all software releases labeled UltraLightClient ‘08. If you already have a UltraLightClient ‘08 license key, a new license key is not required.


    Canoo @ WJAX/SOACon 2008

    November 17th, 2008

    This is just a quick note about the WJAX Java developer conference that take place last week in Munich.

    The conference program was quite balanced and beside the main stream topics about SOA (ServiceOrientedArchitektur – represented by the SOACon conference), Spring, Application Security and OSGi there was a huge number of different topics, which were addressed by several talks.

    Most interesting from my point of view were following sessions:

    • Keynote from Jonas Jacobi: Re-architecting the Web with HTML 5 Communication.
    • Talk from Karsten Lentzsch: Efficient design of swing UI’s.
    • Talk from Angelika Langer: Java programming in the age of multicore.
    • Talk from Dierk Koenig: RESTful JEE with Grails.


    Canoo was exhibiting on a booth, which gave the great opportunity to present and talk about our products UltraLightClient (ULC), the just released language application for the IPhone (using canoo.net), our demo for the new JavaFX platform and fancy UltraLightClient / Swing rich client applications. In addition Canoo members used the presence to keep in touch with existing costumers, contact new ones or presented the company to potential new staff members.

    Canoo Online Quiz

    All the visitors on the booth and all other interested software developers had and still have the possibility to join an online quiz. Its possible to win an iPod touch or one of ten ‘Groovy in Action’ books. The quiz can be found at www.canoo.com/quiz and will end at the 30.11.2008.

    Dierk König, Canoo fellow and author of the ‘Groovy in Action’ book, was holding a groovy workshop and was giving a talk about RESTful JEE with Grails.