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

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).

Published by Jakub Holý

I’m a JVM-based developer since 2005, consultant, and occasionally a project manager, working currently with Iterate AS in Norway.

6 thoughts on “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. 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?

    1. Guess 🙂 Of course I would love to see that. We can either meet at a nice spot all take it over Hangout/Screenhero when it suits, just DM me at Twitter or send me an e-mail (I hope you do not scorn that old-fashioned communication channel :)).

      1. Around 14:00? My place is a construction site at the moment, but we can do it online, in either’s office or at a coffee shop?

Comments are closed.