Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey and Google Guice integration

My question is: why do I need to create AbstractModule when doing JavaSE application and ServletModule while creating application that is deployed on some kind of servlet container like jetty or tomcat? What are the differences between them?

I need to integrate Jersey with Guice. Is it necessary to register presence of Guice for Jersey to use it somehow? Can't I just enable injections and do them everywhere I want (normal classes, filters, handlers, services, DAOs etc.)? And why can't I just configure guice like in JavaSE application, but instead need to use ServletModule?

As far as I see on web, there are many examples of using HK2 services by Guice and vice versa, so I can consider it as important? (necessary?)

Thanks

like image 696
azalut Avatar asked Mar 12 '23 15:03

azalut


1 Answers

An AbstractModule is the basic building block of the bootstrap (configuration) phase of Guice. You always need one or more of that. On the other hand a ServletModule is an specialization which does some configuration for you given the fact that it is running in a servlet container.

From the Guice documentation:

This module sets up the request and session scopes, and provides a place to configure your filters and servlets from.

About the Guice-Jersey integration you certainly need to set it up. It won't work out of the blue. Guice, as any other dependency injection framework, works when it has the control of building your objects. When in doubt ask yourself who creates the object.

With Jersey, and JAX-RS in general, who creates the objects? Not you, you just define them. The container creates them. The JAX-RS runtime. In your case, the Jersey runtime. And Jersey uses internally the HK2 dependency injection framework. So you need to bridge both those frameworks in order to inject a JAX-RS class you have defined with some Guice resources. Or the other way around! That is the reason why there is a HK2-guice bridge. So Jersey would build your objects using HK2 and HK2 will look up your resources also on Guice thanks to the bridge.

A simple example. I use this code to initialize a REST API where I want to inject Guice resources.

@ApplicationPath("api")
public class ApiRest extends ResourceConfig {  
    private static final Logger log = LoggerFactory.getLogger(ApiRest.class);

    @Inject
    public ApiRest(ServiceLocator serviceLocator, ServletContext servletContext) {
        log.debug("Inicialitzant Jersey.");
        packages("net.sargue.app.api");

        GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
        GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
        Injector injector = (Injector) servletContext.getAttribute(Injector.class.getName());
        if (injector == null)
            throw new RuntimeException("Guice Injector not found");
        guiceBridge.bridgeGuiceInjector(injector);
    }
}

Please note that the above example needs the ServletModule registered as it pulls the Guice injector from the ServletContext. Or you can just add the injector to the ServletContext somewhere else. Or just create the injector when initializing the REST API, it depends on your preferences and the application.

like image 133
sargue Avatar answered Mar 25 '23 03:03

sargue