Matthisk
Matthisk

Reputation: 1521

Jersey test dependency injection with Guice

I am unable to use JerseyTest (v2.25) together with Guice dependency injection. My current setup is inspired by an answer on another stackoverflow question. This setup still tries to wire dependency of @Provides annotated classes through HK2, failing my test case. If I remove the .packages() invocation from my test ResourceConfig it seems the listener is not initialized at all and my test cases all return 404's.

This is my current jersey-test setup:

public class MyTestSuite extends JerseyTest {

    @Override
    protected Application configure() {
        return new ResourceConfig().packages("com.example.api");
    }

    @Override
    protected DeploymentContext configureDeployment() {
        return ServletDeploymentContext.builder(configure())
                .addListener(GuiceConfig.class)
                .addFilter(GuiceFilter.class, "guiceFilter")
                .addFilter(ServletContainer.class, "jerseyFilter", Collections.singletonMap("javax.ws.rs.Application", JerseyConfig.class.getName()))
                .build();
    }
}

Here are the classes referenced in the deployment context:

public class GuiceConfig extends GuiceServletContextListener {
    static Injector injector;

    @Override
    protected Injector getInjector() {
        injector = Guice.createInjector(new WebModule());
        return injector;
    }
}
public class JerseyConfig extends ResourceConfig {

    @Inject
    public JerseyConfig(ServiceLocator serviceLocator) {
        Injector injector = (Injector) serviceLocator.getService(ServletContext.class).getAttribute(Injector.class.getName());
        GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
        serviceLocator.getService(GuiceIntoHK2Bridge.class).bridgeGuiceInjector(injector.createChildInjector(new HK2IntoGuiceBridge(serviceLocator)));
        packages("com.example.api");
    }
}
public class WebModule extends ServletModule {

    @Override
    protected void configureServlets() {
        serve("/*").with(ServletContainer.class, Collections.singletonMap(ServletProperties.JAXRS_APPLICATION_CLASS, JerseyConfig.class.getName()));
    }
}

Upvotes: 4

Views: 1498

Answers (1)

Ori Marko
Ori Marko

Reputation: 58822

Instead of writing your own, You can use existing library Jersey Guice Module

you need to bridge the gap between the two DI frameworks. This module aims to do just that by booting Jetty based Jersey server and initializing the bridge between HK2 and Guice.

Getting Started

  • Add JerseyModule to your Guice Injector

  • Configure packages to scan for resources and a port to expose

  • Get instance of JerseyServer and start consuming your Restful resources

 compile 'io.logz:guice-jersey:1.0.8'

Notice you are missing GuiceIntoHK2Bridge

Injector injector = (Injector) servletContext.getAttribute(Injector.class.getName()); 
GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
guiceBridge.bridgeGuiceInjector(injector);

Upvotes: 3

Related Questions