The Holy Java

Building the right thing, building it right, fast

How I Learned to Avoid Magical Dependency Injection And Love Plain Java

Posted by Jakub Holý on November 27, 2013

A short story about the complexity of magical frameworks and dependency injection with a happy ending, featuring Resteasy, CDI, and JBoss.

Once upon time, I have created a JAX-RS webservice that needed to supply data to a user’s session. I wanted to be fancy and thus created a @Singleton class for the exchange of information between the two (since only a user request serving code can legally access her session, a global data exchange is needed). However sharing the singleton between the REST service and JSF handler wasn’t so easy:

  • Originally, the singleton was generic: OneTimeMailbox<T> – but this is not supported by CDI so I had to create a derived class (annotated with @Named @Singleton)
  • While everything worked in my Arquillian test, at runtime I got NullPointerException because the @Inject-ed mailbox was null in the service, for reasons unclear. According to the internets, CDI and JAX-RS do not blend well unless you use ugly tricks such as annotating your service with @RequestScoped (didn’t help me) or use JBoss’ resteasy-cdi module.

Finally I got fed up by all the complexity standing in my way and reverted to plain old Java singleton (OneTimeMailbox.getInstance()) while making testing possible with multiple instances by having a setter an alternative constructor taking the mailbox on each class using it (the service and JSF bean) (using a constructor might be even better).

Result? Actually better testability and simpler code.

Bjørn Borud and Johannes Brodwall were right – plain old Java is better than magical frameworks and magical DI is evil. (Though they would diapprove of JBoss and likely prefered if I used a plain servlet instead of JAX-RS for my very simple case.)

Update: As pointed out by Daniel Kolman now and others previously, dependency injection itself isn’t bad (though some would argue), it is only magic DI that is a problem. You can well do DI yourself using plain old Java – see Bakksjø: The inverse of IoC is Control, Perry: Do-It-Yourself Dependency Injection (pdf; quote: “[..] shows how dependency injection can be accomplished without any framework. The same benefits provided by frameworks can be realized using “do-it-yourself” (DIY) handcrafted code.“; recommended by Google’s test master Miško Hevery who is a fan of DI because it helps with testability).

About these ads

6 Responses to “How I Learned to Avoid Magical Dependency Injection And Love Plain Java”

  1. It’s not DI, it’s JSR-330 and @Inject that is wrong. Or confusing. You don’t need no annotations nor spec for good DI. JSR-330 and @Inject annotation is good for plugin-like modularity, but you can do internal DI well with constructor injection and some simple library.

  2. jhannes said

    Great lesson to share, Jakub.

    I’d love to show you the non-codegeneration SOAP stack in Jetty that I’ve used one day. What do you say?

Sorry, the comment form is closed at this time.

 
%d bloggers like this: