users@jersey.java.net

[Jersey] How to defined resquestScoped injectable object that uses an injected HttpServletRequest with Jersey2

From: Emilie Lavigne <emilie.lavigne_at_gmail.com>
Date: Tue, 22 Jul 2014 08:02:47 -0400

I am building a new REST api using Jersey 2. I'm trying to create a factory that will inject a requestScoped database client based on a header value that comes in through each request. I am using the hk2 approach that comes with Jersey 2.

So far, I have

@Provider
public class DBClientFactory implements Factory<DBClient> {

    private String customerCode;

    @Inject
    public DBFactory(HttpServletRequest request) {
            customerCode = request.getHeader("customerCode");
    }

    @Override
    public void dispose(DBClient dbClient) {
        dbClient.destroy();
    }

    @Override
    public DBClient provide() {
        return new DBClient(Configuration.getDBHost(), customerCode);
    }
}
And in my App config

@ApplicationPath("myApp")
public class App extends ResourceConfig {

    public App() {
        packages(true, "com.my.app")

            .register(new AbstractBinder() {
                    @Override
                    protected void configure() {
                        bindFactory(DBFactory.class).to(DBClient.class).in(RequestScoped.class);
                    }
                })
        ;
    }
}
What is happening is that after one out of roughly 5 server restarts, all requests using an injected DBClient will fail at the dispose step because the HttpServletRequest cannot be resolved, yielding the following error:

Proxiable context org.glassfish.jersey.process.internal.RequestScope_at_4191eec5 findOrCreate returned a null for descriptor SystemDescriptor(
implementation=org.glassfish.jersey.servlet.WebComponent$HttpServletRequestReferencingFactory
If I remove the .in(RequestScoped.class) in my config, the errors stops occurring, however the dispose method is never called, which is not acceptable.

Any ideas?