Using Dependency Injection in a Java SE Application

It would be nice to decouple components in client applications the way that we have become accustom to doing in server side applications and providing a way to use mock implementations for unit testing.

Fortunately it is fairly straightforward to configure a Java SE client application to use a dependency injection framework such as Weld.

The first step is to include the weld-se jar as a dependency in your project. The weld-se jar is basically the Weld framework repackaged along with its other dependencies as a single jar file which is about 4MB.

    <dependency>
        <groupId>org.jboss.weld.se</groupId>
        <artifactId>weld-se</artifactId>
        <version>2.2.11.Final</version>
    </dependency>

 

Implement a singleton which will create and initialize the Weld container and provide a method to access a bean from the container.

import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;


public class CdiContext {

    public static final CdiContext INSTANCE = new CdiContext();

    private final Weld weld;
    private final WeldContainer container;

    private CdiContext() {
        this.weld = new Weld();
        this.container = weld.initialize();
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                weld.shutdown();
            }
        });
    }

    public <T> T getBean(Class<T> type) {
        return container.instance().select(type).get();
    }
}

 

Once you have the context you can then use it to instantiate a bean which in turn will inject any dependencies into the bean.

import java.util.HashMap;
import java.util.Map;


public class MainClass {
    protected String baseDir;
    protected String wldFileLocation;
    protected String dataFileDir;
    protected int timeInterval = 15;
    protected String outputFileDir;

    public void run() throws Exception {
        CdiContext context = CdiContext.INSTANCE;

        //Get an isntance of the bean from the context
        IMatcher matcher = context.getBean(IMatcher.class);

        matcher.setCommodityTradeTimeMap( getDateTranslations(1, "6:30:00 AM", "6:35:00 AM", "6:45:00 AM") );

        matcher.matchTrades(wldFileLocation, dataFileDir, timeInterval, outputFileDir);

    }

What is great is that there are no annotations required on the interfaces or their implementing classes. Weld will automatically find the implementation and inject it in the class where defined. ie. there were no annotations required on the IDataFileReader interface or its implementing classes in order to @Inject it into the Matcher class. Likewise neither the IMatcher interface nor the Matcher class require annotations in order to be instantiated by the CdiContext above.

public class Matcher implements IMatcher {

    //Framework will automatically find and inject
    //an implementation of IDataFileReader

    @Inject
    protected IDataFileReader dataFileReader;

twitter: @RobTerpilowski
@LimitUpTrading

Advertisements

Freight Management System on NetBeans Rich Client Platform

Lynden is a family of transportation and logistics companies specialized in shipping to Alaska [1] and other locations worldwide. Over land, on the water, in the air – or in any combination – Lynden has been helping customers solve transportation problems for over a century.

The Lynden Freight Management System is a NetBeans Platform application [2] which serves a dual purpose as both a planning and freight tracking tool.

  • The Planning module allows terminal managers to see all freight that is currently inbound to their location as well as freight that is scheduled to depart from their location so they can make the most efficient use of their dock space and resources as possible.
  • The Trace module allows customer service personnel to search for customer account information, view the tracking history of any given freight item in the system as well as display any documents related to the shipment, such as bills of lading or delivery receipts.

NetBeans Platform

Lynden has benefited from the NetBeans Platform as it allows developers to focus on the business logic of our applications rather than the underlying “plumbing”.  We are able to leverage built-in support for event handling, enable/disable functionality on UI controls, dockable windows, and automatic updates for our application with minimal work compared to rolling our own framework.

We chose to go the desktop application route as we have a number of existing desktop applications that this application will need to interface with, as well as a commercial set of rich UI components that we have been using for some time now. For the initial deployment, we will be pushing the application installer out to employees PCs via the Landesk remote desktop administration tool.  Future updates to various modules within the application will be done via the update center functionality built into the NetBeans Platform.

Screenshots