users@jersey.java.net

Constructors vs Injection

From: Charles Brooking <public+java_at_charlie.brooking.id.au>
Date: Fri, 24 Apr 2009 18:15:03 +1000 (EST)

Hi all

I've encountered a design issue relating to the use of @Context injection,
and am wondering whether people had thoughts on this.

I have several resource classes extending from a BaseResource class that
includes some convenience methods. In this class I have used field
injection rather than constructor injection to avoid duplication of
arguments in the constructors of subclasses.

public class BaseResource {
    @Context private HttpContext httpContext;

    public Store getStore() {
        return (Store) httpContext.getProperties().get("store");
    }
}

Now for the subclasses. In resource classes containing several methods, it
seems convenient to put common initialisation code in the constructor. For
example, both @GET and @PUT methods might require that an object is
retrieved from some data store. Eg:

@Path("foo/{foo}")
public class FooResource extends BaseResource {
    private Foo foo;

    public FooResource(@PathParam("foo") String name) {
        this.foo = getStore().getFoo(name);
    }

    @GET
    @Produces("text/xml")
    public Response getHTML() { /* read foo */ }

    @PUT
    @Consumes("application/x-www-form-urlencoded")
    public void putForm(...) { /* update foo */ }
}

However, this fails because the getStore() method tries dereferencing the
null pointer of httpContext. The HttpContext instance has not been
injected yet, because the fields of the superclass are injected after the
constructors complete.

This problem has led me to think that perhaps this could be useful

    @Init
    public init(@PathParam("foo") String name) {
        getStore().getFoo(name); // will cause null pointer exception
    }

where the "Init" method is called after dependencies are injected but
before other methods are called.

Have other people hit a similar design problem, and do you have different
ideas?

Later
Charlie