users@jersey.java.net

Re: [Jersey] Re: automatic resource registration and guice

From: Christopher Piggott <cpiggott_at_gmail.com>
Date: Fri, 4 Jun 2010 10:59:56 -0400

> Is it possible to send me a simple reproducible maven project?
I'll have to try to clean/redact it but yeah, if I can't figure this
out I will do that.

I think though that I have a general idea what's going wrong. I
traced through to find out that PackagesResourceConfig wasn't getting
created/run. I tried to figure out why, and noticed that if I set the
system property (PackagesResourceConfig.PROPERTY_PACKAGES) earlier it
seemed to work. But, then, I was getting other exceptions like
"Multiple injectors detected. Please install only one ServletModule in
your web application. While you may have more than one injector, you
should only configure guice-servlet in one of them. (Hint: look for
legacy ServetModules or multiple calls to Servlets.configure())."

I apparently have something screwed up in the way everything gets initialized.

I'm initializing it this way:

        //
        // Create the server
        //
        GrizzlyWebServer ws = new GrizzlyWebServer(8000, ".", false);
// no SSL for now

        //
        // Create the ServletAdapter, whose job is to service requests,
        // and pass them through a filter that we will define
        //
        ServletAdapter sa = new ServletAdapter();

        //
        // Create a filter for the servlet. This filter
        // knows how to dispatch requests to injectors.
        //
        GuiceFilter filter = new GuiceFilter();

        //
        // Create our servlet configuration, which knows how to
        // create an injector for us
        //
        ProtobufServletConfig cfg = new ProtobufServletConfig();

        //
        // Create a container. The container is responsible for
        // managing the lifecycle of all the servlets. The
        // container in jersey-guice knows about the configuration
        // which in turn knows about injectors.
        //

        //
        // TODO: something is very wrong here. Guice is complaining
        // about multiple injectors; grizzly is complaining about multiple
        // ProtobufServletContainers because I was trying to create it
        // by hand here. ProtobufServletContainer is in fact declared
        // as a @Singleton. I'm pretty sure this is where things are going
        // wrong, though.
        //
        ProtobufServletContainer gc =
                cfg.getInjector().getInstance(ProtobufServletContainer.class);

        //
        // Tell the servlet adapter what to use for a container
        //
        sa.setServletInstance(gc);

        //
        // Add the authetication filter
        //
        sa.addInitParameter(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS,
                AuthenticationFilter.class.getName());

        sa.addInitParameter(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES,
                RolesAllowedResourceFilterFactory.class.getName());

        String defaultResourcePackage =
RootResource.class.getPackage().getName();
        sa.addInitParameter(PackagesResourceConfig.PROPERTY_PACKAGES,
defaultResourcePackage);


        //
        // Hook the filter to the servlet adapter
        //
        sa.addFilter(filter, "Guice Filter", null);

        //
        // Add our servlet adapter to the server instance
        //
        ws.addGrizzlyAdapter(sa, null);


So that's the whole initialization sequence, except I didn't tell you
two things. First, ProtobufServletContainer really does nothing
except log a message so I can see that it's being created:

@Singleton
public class ProtobufServletContainer extends GuiceContainer {

    private static Logger log =
LoggerFactory.getLogger(ProtobufServletContainer.class);

    @Inject
    public ProtobufServletContainer(ProtobufServletConfig cfg) {
        super(cfg.getInjector());
        log.debug("Created servlet container");
    }
}


Second, the config ... my config class is, again, not really doing much:

public class ProtobufServletConfig extends GuiceServletContextListener {
    private static Logger log =
LoggerFactory.getLogger(ProtobufServletConfig.class);

    @Override
    protected Injector getInjector() {
        log.debug("Getting injector");
        return Guice.createInjector(new ProtobufServletModule());
    }
}



But see I'm creating the ServletModule there, somethign tells me I
shouldn't be doing that there.

Finally there is the ServletModule but that doesn't do a whole lot ...
it sets up the "other things" that I want to be able to inject. One
confusing thing is that I am also setting PROPERTY_PACKAGES here,
too... from old jersey-guice sample code it seemed that this was the
place to do it ... but that was the start of my problems, because if I
only defined it HERE, then it didn't ever create a
PackagesResourceConfig, which was my original question.


I can tell that, if I don't build an empty project that I can share,
this will be crazy confusing.