How I started this project
Some time ago I went to a Meetup session “Death To Null” by Ties van de Ven from JDriven. During the presentation it became clear that it wasn‘t so much about null checks and NullPointerExceptions but more about Immutability and how it can help keep your software free of bugs and NullPointerExceptions. One of the statements that got me thinking was (something along the lines of): “Java chose the wrong default. Instead of making everything explicitly final when we want an immutable variable, everything should be implicitly final unless the developer makes it explicitly mutable”.
Not knowing that much about the implementation of annotations I thought it would be fun to try to write an annotation which would do exactly that. The first bump I encountered is that annotations cannot modify the programmers source code, or the classes generated from this source code; they can generate new sources or validate code. This quickly turned my attention to project Lombok which does that already. If you use project Lombok for the generation of getters and setters these never show up in your source code. How can your IDE still hint at the existence of the getters and setters?
It turns out that the Java compiler is an iterative process. First the compiler parses your source code into something which is called an AST or Abstract Syntax Tree. Then annotation processors are run to generate sources or do some validation based on your annotations. Compilation errors, such as invalid classes or invalid method calls, are done in phase 3. If, however, an annotation processor generates new sources, the compiler repeats step 1 and 2 before going to step 3.
Project Lombok, and my proof of concept, will use a bit of a hack. Instead of generating new sources with the annotation processor, it modifies the generated AST. This will allow the processor to change the code without touching the source code or the byte code.
A more detailed explanation can be found here. It is a bit dated, but informative.
Building a PoC
For my proof of concept I‘ve decided to create a new maven project. It will have two sub projects, one of them contains the annotation itself and the processor which will process it, the other one contains a test class which uses the annotation.