Evil Field Injection vs. Annotatiomania™ with Lombok

Spring was the framework that has originally brought us dependency injection, e.g. through the utterly magic @Autowired, or the equally magic JEE @Inject. Now in this week, I’ve come across an interesting blog post by Oliver Gierke, a prominent Spring developer. Oliver claims that “field injection is evil.” Hear ye! So, dependency injection isn’t unanimously promoted within Spring / Pivotal?

Oliver makes good points about testability and the fact that injected fields may be null under some circumstances that might not resemble productive environments. He then elaborates on creating immutable state through the usage of constructors. This is also advertised by JIRM, the Java Immutable object Relational Mapper by Adam Gent. And obviously, immutability is also advertised by the creators of the Scala language, who systematically distinguish mutable from immutable collections.

Now, Oliver tries to solve this problem by using Project Lombok, a tool that takes advantage of Java’s annotation processing capabilities as can be seen in this tutorial. Here’s his solution in code:

@RequiredArgsConstructor(onConstructor=@__(@Inject))
class MyComponent {

  final @NonNull MyCollaborator collaborator;

  public void myBusinessMethod() {
    collaborator.doSomething();
  }
}

As you might guess, the above example will generate a constructor taking all members as arguments and annotates that constructor with the JEE @Inject annotation. Now, this solution certainly works and helps avoid boiler plate that you would have if you wrote the constructor code yourself.

But is this really our “brave new world”? Did we really want to put those annotations all over the place? Or is it just me, feeling that Annotatiomania™ is going mad at us? Check out this example from Code That Made Me Cry that makes use of the JPA 2.1 @SqlResultSetMapping annotation. All that code that has been moved from readable, imperative writing to declarative annotations.

Solving things on a language level

Now we can argue whether dependency injection is good or prone to abuse. But this third-party annotation-processing code generation is just crazy. Let’s have a look at how the Scala language resolves such things (as can be seen in this forum thread):

class MyComponent @Inject() 
     (collaborator : MyCollaborator) {

  def myBusinessMethod() {
    collaborator.doSomething
  }
}

Now, this looks much leaner, doesn’t it? I really wish we could have “Scala, the good parts” in Java too. Mixing constructors and immutable state with the class declaration is just plain awesome. This is how an object-oriented language should be done. And it has been repeated in RedHat’s Ceylon.

Stay tuned for a future blog post about borrowing Scala’s and Ceylon’s good parts.

Subtle Changes in Java 8: Repeatable Annotations

Apart from the “big stuff”, related to extension methods, lambda, and the streams API, Java 8 also has a couple of minor, very subtle changes. One of them is the fact that you can now annotate an object several times with the same annotation!

An example taken from the tutorial:

@Alert(role="Manager")
@Alert(role="Administrator")
public class UnauthorizedAccessException { ... }

For this to work, your @Alert annotation has to be meta-annotated with java.lang.annotation.Repeatable.

Tools, which heavily rely on annotation processing may need to review their code to get ready for Java 8. Existing methods, such as AnnotatedElement.getAnnotations(), have not been retrofitted to return repeatable annotations. Instead, other, new methods, such as AnnotatedElement.getAnnotationsByType(Class) and AnnotatedElement.getDeclaredAnnotationsByType(Class) have been added to the JDK, in order to be able to discover repeated annotations on any element.

More authoritative information can be found here: