Monday, August 22, 2011

Tired of Getters and Setters? Lombok them!


I love Java. There is a lot of amazing stuff being build with it every minute and I really love being part of that community. But, to be honest, there is one single thing, that I hate. That is the JavaBeans™ architecture.
Not completely but the basic requirements to have a nullary constructor and property access using getter and setter methods. All this is stupid overhead, hard to maintain and change. But there is a little helper out there, that made my life more easier. It's project Lombok. Here is a very short overview about using Lombok with ManagedBeans.

Getting Started

Grep your favorite IDE (Eclipse/NetBeans) and start your new Maven based Java EE 6 web-project. Add the Lombok dependency to your pom.xml:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>0.10.0</version>
<scope>compile</scope>
</dependency>
And you are done. If you are not using Maven, get your copy of the lombok.jar from the project's website. That's all. Your done.

Coding the ManagedBean with Lombok

Create a new class named "Customer" and add some String fields: public class Customer {
private String name;
private String sure_name;
private String nickname;
}
But what happens if you try to use this one as @ApplicationScoped @ManagedBean? For sure your JSF runtime will complain about missing properties and constructors. But instead of adding all those boilerplate code you simply add @Data as an additional annotation to your class which should look like this now: @ManagedBean
@ApplicationScoped
@Data
public class Customer {
private String name;
private String surename;
private String nickname;
}
Now get a simple JSF frontend and add some: <h:inputText id="name" value="#{customer.name}" /> for every field in your bean to it and you are done. Everything works. And nobody is complaining about missing properties anymore!

What happened?
The offered Lombok annotation @Data simply tells your IDE to generate all the boilerplate code for you silently. And this is done during compile time, so you usually don't have to care about lombok being on your runtime path at all. There are some exceptions to this rule with other Lombok features but it's true for this simple example. @Data especially is a convenient shortcut annotation that bundles the features of @ToString, @EqualsAndHashCode, @Getter / @Setter and @RequiredArgsConstructor together: In other words, @Data generates all the boilerplate that is normally associated with simple POJOs (Plain Old Java Objects) and beans: getters for all fields, setters for all non-final fields, and appropriate toString, equals and hashCode implementations that involve the fields of the class, and a constructor that initializes all final fields, as well as all non-final fields with no initializer that have been marked with @NonNull or @NotNull, in order to ensure the field is never null. If you look at the generated source you see that the compiled file is there and contains all your well known boilerplate:
>javap Customer
Compiled from "Customer.java"
public class net.eisele.lombokdemo.Customer {
public java.lang.String process();
public net.eisele.lombok_jsf.Customer();
public java.lang.String getName();
public java.lang.String getSurename();
public java.lang.String getNickname();
public void setName(java.lang.String);
public void setSurename(java.lang.String);
public void setNickname(java.lang.String);
public boolean equals(java.lang.Object);
public boolean canEqual(java.lang.Object);
public int hashCode();
public java.lang.String toString();
}

That's all?
Not really :) There are some more features Lombok has to offer. e.g. a simple @Log which gives you access to a private static final java.util.logging.Logger log
field to simply log what's happening. You can also have a @Log4j, @CommonsLog or even a @Slf4j as alternatives. If you are looking for all the goddess, look at the project's feature overview page.

Risks?
One could argue that having all those fancy stuff done by a compiler could lead to unexpected results and probably introduces errors nobody likes. Right. But even if you don't like all those automated and transparent generation, you could simply Delombok your source files. This would simply replace all lombok annotations with the generated code and gives your access to a complete codebase. So it's a calculable risk using Lombok and I must admit: I love it.