A Quick Tour of Joda Beans
One of my big headaches about Java is the amount of boilerplate code you need to put in to make things work right. Especially in POJOs. I mean, is the solution to always run “generate getters/setters” in the IDE? And how about an equals
and hashCode
?
In the past I’ve used Project Lombok to do this for me. It’s all annotation based – @EqualsAndHashCode
does exactly what you would expect it to. You can make @Data
to do all the things. The problem with Lombok is how it accomplishes this is by class transforms at compile time. So you need something in your build process to do the transforms. Not only that, you have IDE Support – most will simply error out unless you have the IDE plugin. It may not seem like a big deal, but if you change machines, and suddenly you have compile errors, you have to remember what you did. Or you have to help onboard others and they wonder why they get compile errors on first checkout. From a technical perspective – what if you upgrade to the latest JVM and Lombok doesn’t support that version yet.
A few weeks ago I stumbled onto Joda Beans, which tries to solve the same boilerplate problem with another method – code generation. So instead of getting in the middle of the build process to accomplish it, you create a skeleton of the file, run a build task, and it fills in the blanks. No IDE plugins, and you have the full source checked in. Need to update the class? Just add the property and then run the task again.
So I played around with Joda Beans and found out that I liked a lot about it. It gives you more things than Lombok does as well. So I’ve posted some of my experiments on GitHub.
For example, I wrote this class:
@BeanDefinition import org.joda.beans.*; import org.joda.beans.gen.BeanDefinition; import org.joda.beans.gen.PropertyDefinition; public class Book implements ImmutableBean { @PropertyDefinition(validate = "notEmpty") private final String title; @PropertyDefinition private final Author author; @PropertyDefinition private final LocalDate publishedDate; }
If you try this in your IDE, will note that this has errors in it. That is expected. Run ./gradlew jodaGenerate
and you will see the class fill out. It will look similar to the class I have in GitHub. Because the Book
class implements ImmutableBean
, a Builder will also automatically be generated as well.
Note that Book
has an Author
property. That class is similar and can be seen here. Note that his class is mutable so no Builder was generated.
One of my favorite things that Joda Beans give you is a property accessor. A simple and contrived example:
MetaProperty<String> titleProperty = book.metaBean().metaProperty("title"); System.out.println("titleProperty.get(book) = " + titleProperty.get(book));
That doesn’t seem that special. But note that titleProperty
is generic – works for any class with a title
property!
Magazine magazine = new Magazine(); magazine.setTitle("Dr Dobbs"); System.out.println("titleProperty.get(magazine) = " + titleProperty.get(magazine));
And Joda Beans also includes it’s own serialization scheme. Here is how to get JSON:
String json = JodaBeanSer.PRETTY.jsonWriter().write(book);
And it looks like this:
{ "@bean": "com.squarepegsystems.Book", "title": "Snow Crash", "author": { "lastName": "Stephenson", "firstName": "Neal" }, "publishedDate": "1992-06-01" }
The Main class has a sample of everything I talked about from above. If you want to run it, just type ./gradlew run
from the command line.
I haven’t used Joda Beans in a production project yet, but I really like the feel of it. I’m a bit leery of code generation but the other things you get (Builders, property accessors, etc) seem a lot more powerful than mere syntax sugar.