Archive for the ‘dependency injection’ Category


Configuring ActiveMQ transactions in Spring

It’s easy to configure Message Driven POJOs over ActiveMQ with Spring, but slightly more involved once you want to get transactions working correctly; here’s how to do it.

Start with a basic DefaultMessageListenerContainer config.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:amq="http://activemq.apache.org/schema/core"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.0.xsd

http://activemq.apache.org/schema/core

http://activemq.apache.org/schema/core/activemq-core.xsd">

    <!-- setup an embedded JMS Broker for testing purposes -->
    <amq:broker id="my-broker" useJmx="false" persistent="false" brokerName="localhost">
        <amq:transportConnectors>
            <amq:transportConnector uri="tcp://localhost:61616" />
        </amq:transportConnectors>
    </amq:broker>

    <bean id="amq.connectionFactory"
            class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL"
                value="tcp://localhost:61616?jms.redeliveryPolicy.maximumRedeliveries=1" />
    </bean>

    <bean id="consumer.connectionFactory"
            class="org.springframework.jms.connection.CachingConnectionFactory">
        <constructor-arg ref="amq.connectionFactory" />
    </bean>

    <bean id="consumer.messageListener"
            class="net.jakubkorab.amq.CountingMessageListener" />

    <bean id="consumer.jmsContainer"
            class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="consumer.connectionFactory" />
        <property name="destinationName" value="sample.messages" />
        <property name="messageListener" ref="consumer.messageListener" />
    </bean>
</beans>

An embedded broker is started, and a MessageListener (CountingMessageListener) is set up to pick up messages from a queue (sample.messages). MessageListenerContainers should always sit over a CachingConnectionFactory (see the Spring docs for details). So what happens if the listener throws an exception?

According to the intent of the URI configration on the connection factory, we’d like to see the broker attempt to redeliver the message again, and if that fails the message should end up in a dead letter queue (ActiveMQ.DLQ). However, if you test it, that’s not what happens at all.

You will not see any further redelivery attempts and there’s nothing in the dead letter queue. Why? Because you haven’t configured up a TransactionManager, Spring’s DefaultMessageListenerContainer picks up the message and immediately acknowledges it. As far as the broker is concerned, it’s job is done.

So let’s remedy this by adding one.

    <bean id="local.transactionManager"
            class="org.springframework.jms.connection.JmsTransactionManager">
        <!-- can also refer to amq.connectionFactory -->
        <property name="connectionFactory" ref="consumer.connectionFactory" />
    </bean>

    <bean id="consumer.jmsContainer"
            class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="consumer.connectionFactory" />
        <property name="destinationName" value="topic:sample.messages" />
        <property name="messageListener" ref="consumer.messageListener" />
        <!-- add a reference to the transaction manager -->
        <property name="transactionManager" ref="local.transactionManager" />
    </bean>

This uses Spring’s own TransactionManager instance to now make sure that the message is consumed with no issues. Any exceptions thrown will now cause the broker to redeliver the message according to the redelivery policy specified in the connection URI, and once that is exceeded to send the offending message to the dead letter queue.


Update 13/09: Thanks to Sue Macey for pointing out this fragment from the Spring docs:

Local resource transactions can simply be activated through the sessionTransacted flag on the listener container definition. Each message listener invocation will then operate within an active JMS transaction, with message reception rolled back in case of listener execution failure. Sending a response message (via SessionAwareMessageListener) will be part of the same local transaction, but any other resource operations (such as database access) will operate independently. This usually requires duplicate message detection in the listener implementation, covering the case where database processing has committed but message processing failed to commit.


This is sufficient for most cases. However let’s say you want to update a database via your listener. Transactions ought to be atomic, and the JmsTransactionManager won’t do the job for you here – you need to bring out the big guns.

Once you start managing more than one resource (broker, database etc) in a transaction, you bring in a sizeable overhead. Distributed transactions will involve some sort of two-phase commit protocol, and the chatter adds processing time to each operation. Should you decide that it’s definitely something you want to do, JTA is the tool for the job.

If you’re running in a full JEE container and using a DataSource that supports XA transactions (some do, some don’t), you’re in luck:

    <bean id="consumer.messagerListener"
            class="net.jakubkorab.amq.DBAwareMessageListener" >
        <!-- listener uses a JdbcTemplate with a DataSource defined elsewhere -->
        <property name="dataSource" ref="xa.dataSource" />
    </bean>

    <!-- use the XA-specific version of the connection factory -->
    <bean id="amq.connectionFactory"
            class="org.apache.activemq.ActiveMQXAConnectionFactory"
            depends-on="my-broker">
        <property name="brokerURL"
                value="tcp://localhost:61616?jms.redeliveryPolicy.maximumRedeliveries=1" />
    </bean>

    <bean id="jta.transactionManager"
            class="org.springframework.transaction.jta.JtaTransactionManager"
            depends-on="my-broker"/>

    <bean id="consumer.jmsContainer"
            class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="consumer.connectionFactory" />
        <property name="destinationName" value="sample.messages" />
        <property name="messageListener" ref="consumer.messagerListener" />
        <!-- change the transaction manager reference -->
        <property name="transactionManager" ref="jta.transactionManager" />
        <!--
            now tell the broker that it's involved in a transaction; this has the same effect
            as creating a transacted session using the JMS API
        -->
        <property name="sessionTransacted" value="true" />
    </bean>

The JtaTransactionManager will pick up and manage transactional resources using the JTA implementation from the server. However, you need a full JEE server for this. Tomcat for example, does not come with JTA. Neither for that matter will JUnit, which makes testing your transaction config problematic. In these cases, you need to make use of an external JTA implementation, such as Atomikos or JTOM.

Atomikos’ approach to transaction management outside of the server is to place their own wrappers around your resource definitions. Their transaction manager will then scan the Spring ApplicationContext to find these. To set it up takes a final step:

    <!-- implementation-specific wrapper used by the transaction manager -->
    <bean id="xa.connectionFactory" class="com.atomikos.jms.AtomikosConnectionFactoryBean">
        <property name="uniqueResourceName" value="amq1" />
        <property name="xaConnectionFactory" ref="amq.connectionFactory" />
    </bean>

    <bean id="jta.transactionManager"
            class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager">
            <bean class="com.atomikos.icatch.jta.UserTransactionManager"
                    init-method="init"
                    destroy-method="close">
                <property name="forceShutdown" value="false" />
            </bean>
        </property>
        <property name="userTransaction">
            <bean class="com.atomikos.icatch.jta.UserTransactionImp">
                <property name="transactionTimeout" value="300" />
            </bean>
        </property>
    </bean>

The JtaTransactionManager is configured to use an external underlying TransactionManager implementation, and wrappers are provided around the resources.

Assuming interaction with an HSQLDB instance, which doesn’t support XA transactions, you would add a further:

    <!-- HSQLDB is not XA compatible so we wrap that using a special Atomikos NonXA to XA DataSource -->
    <bean id="xa.dataSource" class="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean">
        <property name="uniqueResourceName" value="hsqldb" />
        <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
        <property name="url" value="jdbc:hsqldb:mem:myTestDb" />
        <property name="user" value="sa" />
        <property name="password" value="" />
        <property name="poolSize" value="3" />
    </bean>

When using a database that supports XA, you would use a com.atomikos.jdbc.AtomikosDataSourceBean instead.

The above should get you going, but remember that it’s important with any kind of transactional config to test that it actually works.

Rich UI -> Component Based

A client of mine is developing a web application. The framework decision was made up front – Spring Webflow/MVC. I like Webflow. Its state machine based continuations concept is very cool. It lets you easy deal with things like back buttons, switching into a side piece of application flow (think needing to log in before continuing on to a section of the site) and maintaining a history of the state of a flow (where going back means using the application state as it was at that point in time). In short it’s pretty powerful stuff.

Only one problem – the application front end has been prototyped and signed off on by analysts used to working with desktop software.

Put simply, it’s expected to do some pretty crazy stuff. Think multiple layers of tabs, where the user can switch between different parts of the app without saving, navigating around fields from a central list of items that need correcting. Erk! The amount of hoops that have been had to be jumped through to get the requirements working have been huge, and it only keeps getting more complex. Without Webflow, I can’t imagine how something of this complexity could have been addressed. Classic web frameworks wouldn’t help on this one without some serious
bastardization.

The thing is, while Webflow makes it achievable, it’s not the right tool for the job. The interface requirements are too complex to easily do this stuff. Using a framework that ties you to the request based programming paradigm is the wrong way to go.

Put simply, we wouldn’t have the same sort of problems if the system we are building was constructed on a component based framework like Tapestry, JSF, or Wicket. Components have state, the page is composed of them and you react to events – “the button was clicked”. No more
request. No more session. Need to pull together info from multiple tabs? No worries – do it when the “I’m finished” button has been clicked. It takes a big mind shift to step away web concepts, but it’s worth it. At the very worst, there’s a new piece of kit in your toolkit that you can select for the task at hand.

As your tools become more capable, the requirements from your clients get more demanding. Your next web app interface won’t look like the last one you did. It will look like the latest whizz-bang offering from the latest flash in the pan start-up. Your clients use the net. They can see what others are doing. They expect that you can deliver the same. This is especially the case for internally used desktop replacement apps. If you don’t have the tools, you’re in for some late nights.

If it looks like a desktop app running in a browser, forget your father’s MVC framework – it’s just won’t cut the mustard.

It seems like a happy coincidence for Ruby on Rails that Web 2.0 apps emphasise simplicity. Classic MVC is not up to the task of rich UI.

Thoughts on Mixing EJB3 and Spring

A few weeks ago I blogged about Spring and EJB integration, but something just did not sit well with me. Why would you want to do this at all?

I like Spring. Its myriad components make my life simpler. I can write the business code I need to faster without worrying as much about the plumbing aspects. The Spring contributors have put a lot of thought into reducing the lines of code that I as an application developer need to write. Brilliant! My stuff can be easily tested by applying DI principles and this makes me happy as it takes less effort to make the end client happy.

I have access to all of the services on the JEE platform, including transactions, naming and management and can use it as is appropriate to the task at hand. EJB is also a way of doing the same thing. If two things do the same thing, then why would you want to use them both?

I have read a lot of opinions on this question (actually, most have been on which is better, which is meaningless in this context), and have come to the conclusion that I don’t. The problem space is such that you get no additional benefits in tying the two together.

Spring is a platform, an over-arching container, a way of structuring applications and a tool set. EJB is a component model for developing the business tier that ties in directly into your JEE server. Where they cross over is that they allow your application to access the underlying services in such a way that you don’t deal with them when you write your business code.

You would use Spring to manage your business tier when you want to write a Spring application – ORM templates, Webflow, Web services, Remoting API. You would use EJB when you want to write something like a Seam application – JSF, tying in directly to a business tier that manages your persistence, jBPM for process management etc.

The question is what Style of application are you building – is it multi-tier with clear delineation of function (web tier, business tier, data access tier, anemic model), which is what Spring excels at, or do you want a tighter relationship between your tiers with a framework that manages everything in a much more integrated way (not saying that you can’t achieve this with Spring).
This is what I would term a soft decision – it’s less about technical merit and more about the vibe. Where software design meets gut feel.

Sticking EJB into a Spring app is clunky. It does not sit well. Even the stuff that you may have considered EJB for in that past have equivalents in this new world. Remoting (largely out of favour in preference to WS), listening on the end of JMS queues (which I like MDBs for) have nicer corresponding elements that sit better in Spring.

The application style is up to you at the end of the day. Whether you like the full prescribed JEE stack using EJB, or mix and matching the frameworks that you are productive in with Spring, run with it. Just keep in mind the problems that each piece of your application is trying to solve, and don’t double up. It will only make your applications unnecessarily complex.

As a side note, my current project has dropped EJB3 from the rest of the (Spring) stack.

Spring Web Services 1.0 Released

The Spring guys have released version 1.0 of their web services framework. The framework contains:

  • simplified methods to create contract-first web services (Java classes from XML schemas)
  • a clean client-side API
  • standardized access to O/X (object to XML) mapping tools like Castor, XMLBeans and JiXB that allow you to marshal and unmarshal XML easily

As we have come to expect, all of these components can be mixed and matched and used as standalone components. After my first look, I’m really impressed. Java web services don’t get much easier than this.

How to test the middle tier of a Spring application

Since the advent of dependency injection (DI) as a staple of enterprise development using tools such as Spring or Guice, your code has become a lot easier to test. You no longer need to code up voodoo such as plugging in dummy resource locators or the like based on some random environment variable to tell your code to switch into “test mode”. Everything is a POJO with interfaces as dependencies rather than classes, which means that it can be easily tested as a POJO. Nevertheless, it still surprises me as to how many people don’t know how to do this. Perhaps it is the perception that you need to have a running back end to test a service tier, or that you need the rest of the system to test a web front end. Not so.

Enter the mock object. According to Wikipedia – “mock objects are simulated objects that mimic the behavior of real objects in controlled ways”. And thanks to freely available Java toolkits such as EasyMock and jMock, making them available to your tests is as easy as plugin in a Jar file into your IDE. I’m a heavy user of EasyMock, so what follows is a simplified example of a jUnit test testing the middle tier of your typical DI-based application.

The following example deals with the following classes:

  • WorkItem – a simple value object
  • WorkItemException – an exception
  • WorkItemService – an interface of a middle tier class
  • WorkItemDao – an interface to the data layer of our application. This is what we are going to mock up.
  • WorkItemServiceImpl – an implementation of that class. This is what we are going to test.
  • WorkItemServiceImplTest – our test class

First, let’s get the uninteresting classes out of the way. Our WorkItem is just a bean that gets passed between the layers:

package jkorab.example.mock;

public class WorkItem {
 int workItemNo;

 public int getWorkItemNo() {
    return workItemNo;
 }

 public void setWorkItemNo(int workItemNo) {
   this.workItemNo = workItemNo;
 }
}

The WorkItemException is an exception that gets thrown:

package jkorab.example.mock;

public class WorkItemException extends Exception {
  private static final long serialVersionUID = 1L;
}

Now we come to the class that normally sits in the business tier of our application:

package jkorab.example.mock;

public interface WorkItemService {

  /**
   * Trivial method. Given a workItem number > 0, returns a workItem instance.
   * Used to show how you might test the wrapping of an exception.
   *
   * @return WorkItem or null.
   */
  public abstract WorkItem generateWorkItem(int workItemNo);

}

Let’s take a look at the interface of the class it uses to do its work:

package jkorab.example.mock;

public interface WorkItemDao {

  /**
   * Given a workItem number > 0, returns a workItem instance.
   * @param workItemNo workItem number
   * @return WorkItem if workItemNo > 0.
   * @throws WorkItemException if workItemNo <= 0.
   */
  public WorkItem getWorkItem(int workItemNo) throws WorkItemException;

}

Our example is, as is the spirit of most tutorials, pretty contrived. The top tier of our application wants to load a WorkItem, so it passes a work item number to the service tier. The service tier gets the work item, and if it cannot find it, returns null. The DAO on the other hand, gets a work item number and it the number is less than or equal to 0, it throws an exception, otherwise it loads the WorkItem.

Here’s the implementation of the WorkItemService:

package jkorab.example.mock;

public class WorkItemServiceImpl implements WorkItemService {
  private WorkItemDao workItemDao;

  public void setWorkItemDao(WorkItemDao workItemDao) {
    this.workItemDao = workItemDao;
  }

  /* (non-Javadoc)
   * @see jkorab.example.mock.WorkItemService#generateWorkItem(int)
   */
  public WorkItem generateWorkItem(int workItemNo) {
    WorkItem workItem = null;
    try {
      workItem = workItemDao.getWorkItem(workItemNo);
    } catch (WorkItemException workItemException) {
      // log and continue. we'll return null.
    }
    return workItem;
  }
}

The class here is doing what the interface “said on the tin”. In addition it has a setter so that the DI container can supply it with a DAO implementation. That’s where our hook is that will enable us to test the service without an actual DAO implementation.

The first thing we need in order to write a test class is a mock DAO. This is the component that the service class will call. In addition we will also need a mock control. Think of this as a component that instructs your DAO as to how it should behave – kind of like a way of programming your Tivo/Set top box/VCR (for those who still have one ;) ).

MockControl control = MockControl.createControl(WorkItemDao.class);
WorkItemDao mockDao = (WorkItemDao) control.getMock();

WorkItemServiceImpl service = new WorkItemServiceImpl();
service.setWorkItemDao(mockDao);

The MockControl class is used to get an instance appropriate to the interface we are mocking up. From this, calling getMock() will return to us an implementation of our DAO interface which we then set on the instance of the class we are testing. This would normally be done in the setUp() method of your jUnit test class, so that each of your tests is guaranteed to get a mock instance in a fresh state, which you can then play with.

In our test method, we can then get on with doing some work. First, we tell our DAO exactly how we would like it to behave:

// set the methods that you expect to be called
mockDao.getWorkItem(1);

// set the return value
WorkItem returnedWorkItem = new WorkItem();
returnedWorkItem.setWorkItemNo(1);
control.setReturnValue(returnedWorkItem);

// reset the control object to play back our script
control.replay();

The last line tells the mock control object that the mock DAO is now in a state where the test can be run on it.

WorkItem workItem = service.generateWorkItem(1);
assertNotNull(workItem);
assertEquals(1, workItem.getWorkItemNo());

// verify that the methods we expected to be called on the mock object
// were actually called
control.verify();

The last line tells the control object to check itself to ensure that all the methods that we told it would be called were in fact called. It will throw an Exception if they weren’t causing our test to fail.

The behaviour described above can be used to test the behaviours of your service class under any circumstances. We can mock up the throwing of an Exception, unexpected behaviours, whatever we want. Here’s the full test class:

package jkorab.example.mock;

import jkorab.example.mock.WorkItem;
import jkorab.example.mock.WorkItemDao;
import jkorab.example.mock.WorkItemException;
import jkorab.example.mock.WorkItemServiceImpl;

import org.easymock.MockControl;

import junit.framework.TestCase;

public class WorkItemServiceImplTest extends TestCase {
  private MockControl control;
  private WorkItemDao mockDao;
  private WorkItemServiceImpl service;

  public void setUp() {
    control = MockControl.createControl(WorkItemDao.class);
    mockDao = (WorkItemDao) control.getMock();

    service = new WorkItemServiceImpl();
    service.setWorkItemDao(mockDao);
  }

  /**
   * Checks that a WorkItem will be returned if the class receives a workItem
   * number greater than 0.
   *
   * @throws WorkItemException
   */
  public void testGenerateWorkItem() throws WorkItemException {
    // set the methods that you expect to be called
    mockDao.getWorkItem(1);
    // set the return value
    WorkItem returnedWorkItem = new WorkItem();
    returnedWorkItem.setWorkItemNo(1);
    control.setReturnValue(returnedWorkItem);
    // reset the control object to play back our script
    control.replay();

    WorkItem workItem = service.generateWorkItem(1);
    assertNotNull(workItem);
    assertEquals(1, workItem.getWorkItemNo());

    // verify that the methods we expected to be called on the mock object
    // were actually called
    control.verify();
  }

  /**
   * Checks that a null will be returned if the class receives a workItem
   * number equal to 0 rather than throwing an exception.
   * @throws WorkItemException
   */
  public void testGenerateWorkItemNullValue() throws WorkItemException {
    // set the methods that you expect to be called
    mockDao.getWorkItem(0);
    // set the control to throw an exception
    control.setThrowable(new WorkItemException());
    control.replay();

    WorkItem workItem = service.generateWorkItem(0);
    assertNull(workItem);
  }
}

This is a great way to test, not only because of its simplicity, but also it being future proof. Let’s examine another way of writing the same tests without using mock objects:

WorkItemDao mockDao = new MockDao() {
  public WorkItem getWorkItem(int workItemNo) throws WorkItemException;
    WorkItem returnedWorkItem = new WorkItem();
    returnedWorkItem.setWorkItemNo(1);
  }
};

WorkItemServiceImpl service = new WorkItemServiceImpl();
service.setWorkItemDao(mockDao);

WorkItem workItem = service.generateWorkItem(1);
assertNotNull(workItem);
assertEquals(1, workItem.getWorkItemNo());

At first glance, coding up an anonymous class looks like less work, but consider the following:

  • if your class is more complex than this (and to be honest, most are) then you will end up with potentially dozens of anonymous implementations.
  • if the DAO has more than one method, you will end up with a lot of code that does nothing.
  • if the interface on your DAO changes then you will end up with a lot of tests that won’t compile, because your classes no longer match the interface.

This just isn’t the case with mock objects. Mock objects are created at runtime, and you only have to define the behaviours that you are interested in. The technique can also be used to test existing code – refactor your dependencies to an interface, use DI or a constructor if this isn’t an option, and voila, a testable class. 100% code coverage, and future-proof. No more excuses.

If you are interested in more info on mock objects check out the MockObjects blog.

Getting up to speed on EJB3 and Spring

Another contract, another technology set. Having successfully avoided working in EJB2 after getting certified in it by Sun (only to work out just how badly it smelt ;) ), my initial foray into its successor has been much nicer. The job in question specified Spring and EJB3 as technology requirements, so having Sprung in anger, I approached it from that angle as well as getting myself up to speed on the EJB3 changes.

Firstly, while they may be viewed competing technologies they can be complementary ones. Spring is a framework which aside from dependency injection gives you a bunch of goodies for the various tiers in your application that make your life easy and cut down on boiler-plate code. EJB3 is a model for building server-side components that gives you services such as concurrency, transaction management, persistence, object distribution, naming, and security. And it’s finally getting to be the technology that it should have been.

The changes in EJB since version 2:

  • All EJBs are now POJOs. Woohoo! Nothing to subclass. Easy to test!
  • You don’t have to implement a whole bunch of container callback methods – write up the ones you want (if you want them) and annotate with the event that triggers. I am finally seeing the power of the annotation here. Think optional mini-interface.
  • Remote interfaces don’t have to differ from local interfaces only by a RemoteException that needs to be handled around each invocation.
  • Persistence via entity beans has been reworked into it’s own API (JPA) which means it can be used outside a container. Stuff that implements it? Hibernate, Toplink… all the stuff you already know.

In fact… a stateless session bean does not look that far removed from a stateless class your existing Spring application used in its service layer. A smattering of annotations, a hook for Spring to weave its DI magic and a change of config is all it takes for your Spring app to use all of the goodies that EJB gives you via local session beans. You still have to understand the EJB life cycle but you don’t get something for nothing.

EJB3 supports dependency injection out of the box, but it’s kind of limited. The only things that are injected are other EJBs, and an EntityManager object (used to access the ORM – kind of naff since we have all been happily DAOing for ages and like to separate our data access from our business logic). If you wanted to use DI to inject stuff at a finer level (such as DAOs, JavaMail sessions etc.), you still have to use an actual DI container – hence Spring. The hook feels a bit clumsy, in that your EJBs have to subclass a Spring class and implement a callback, but it makes sense when you understand the bean life cycle. Not quite painless but pretty good nevertheless.

Spring strikes again in the DAO/EAO layer (E for Entity, get it?) with it’s superb template approach via the JpaDaoSupport class, cutting boiler-plate code in that layer to nothing. Mmm… warm fuzzy feeling ahead:

public class UserDao extends JpaDaoSupport {  public List getAdminUsers() {    return getJpaTemplate().find("select u from User u where type=?1", "admin");  }}

EJB 3 in Action is worth the money just for the chapter covering the Spring integration. The rest of the book is also quite good both from the point of view of a new developer and people like me who are getting up to speed on the changes from earlier versions. The latest edition of the definitive guide, Enterprise JavaBeans 3.0 by Burke and Monson-Haefel (who retired from writing before this edition) is also exceptional, but you should check out the relevant Spring documentation to supplement it.

My take on this is that Spring gives you good stuff, and EJB gives you good stuff as well – and now without the pain. Use one, or the other, or feel free to mix and match. It’s nice to know that you don’t have to trade one for the other.

What bugs me about Guice

Last week I switched a basic Spring app to Guice, the new dependency-injection framework from Google. It’s nice, it’s quick, and it does what it says on the box, but one thing bothers me. I know it’s not really logical, but it’s like a rock in my shoe – I need to import com.google.inject annotations (@Inject) into the classes that need an object injected. I have only done the most basic quick start stuff, and you may not need it, but that’s what the quick start says.

OK, so the POJOs that make up your app are still container agnostic, but somehow it kind of smells to be putting stuff that details how your container is going to manage the code into your code – even if it is only metadata. Maybe it is not so much the actual metadata per se. After all, describing usage of a class is what it is supposed to do. But com.google imports? Even if it was org.something it would be better, but something just doesn’t sit well here. I may need to digest what this means. It’s really skirting that line of putting runtime details back into POJOs. Hmm…

Dependency injection killed the factory pattern

I was having a play with Guice (http://code.google.com/p/google-guice/), the new dependency injection framework from the folks at Google, and something quite profound happened. I realised that having used Spring for a while now, it had been ages since I had to code up a factory class for pretty much anything.

No more weird JNDI lookup code, no switching in test classes if some weird ThreadLocal is set to "test". A whole huge chunk of plumbing code has been washed away. I no longer have to worry about things like whether I’m going to be running my test cases in or out of container and how stuff under the bonnet is going to do lookups in both case. I don’t care whether my JUnit/TestNG tests are being run in Eclipse or Ant. My code is cleaner, easier and faster to test, and far simpler. Any time I can’t test my code as POJOs, I feel like that dream you had in primary school where you turn up to school and you’re not wearing any pants (OK, maybe that’s just me).

So OK, your DI framework of choice still has a factory in there somewhere to auto-wire, or run off config, or annotations or whatever… but the point is "You’re Not The One Doing It" (YNTODI – original abbreviation, I checked). The less potentially error-prone code I have to write (hey, bugs are part of the job) the better.

A huge tip of the hat to the Google lads as well, the annotation based Guice looks like a really nice drop-in for the DI aspect of Spring. Keep up the good work, and putting in the hard yards so guys like me don’t have to ;)