29

Is there any sample code demonstrating how to use guice-servlet with Jersey 2.0?

Gili
  • 76,473
  • 85
  • 341
  • 624
  • 1
    Any particular reason you want to use guice-servlet? Jersey 2.0 is fully integrated with HK2 dependency injection out of the box, which (as far as I have seen) is very similar to Guice DI. Have a look at http://stackoverflow.com/questions/16216759/dependency-injection-with-jersey-2-0/17133081#17133081 for more information. – joscarsson Sep 07 '13 at 13:39
  • 7
    @joscarsson, I have no desire to learn yet another DI framework. HK2 is not nearly as mature as Guice both from a functionality and community perspective. – Gili Sep 07 '13 at 19:24

8 Answers8

9

https://github.com/Squarespace/jersey2-guice seems to be the first genuine Guice integration for Jersey 2 but it requires version 2.11+.

NOTE: I haven't tested this, but the idea is sound.

Gili
  • 76,473
  • 85
  • 341
  • 624
  • I just whipped up a quick example using jersey2-guice with embedded Jetty at [github.com/hansenc/jersey2-guice-example](https://github.com/hansenc/jersey2-guice-example) and it seems to work as advertised. – Chris H. Dec 19 '14 at 05:12
  • 1
    There are problems with Jersey 2.20+. 2.19 works fine. Issue https://github.com/Squarespace/jersey2-guice/issues/32 Good example http://www.nailedtothex.org/roller/kyle/entry/lean-example-of-tomcat-82 – Alex Chevelev Nov 14 '15 at 14:00
  • We have been using Squarespace/jersey2-guice in production for multiple web services. But now (March 2018), it's stuck at Jersey 2.22.2. I'm looking at alternative that are compatible with Jersey 2.25+. – Manu Manjunath Mar 14 '18 at 09:05
5

Yes, I've adapted an example and it's available here - https://github.com/piersy/jersey2-guice-example-with-test

I've updated the example code now, its got a test using jetty and another using tomcat.

PiersyP
  • 4,353
  • 2
  • 28
  • 32
  • Only works with Glassfish. A more generic example is needed that will work on Tomcat, Jetty, etc. – mjaggard Jul 25 '13 at 14:30
  • Hi mjaggard, I'm not sure I understand your point, in the example posted I have used jetty not glassfish? – PiersyP Jul 25 '13 at 14:46
  • Sorry, I guess I got confused by the use of HK2. Why is that being used? – mjaggard Jul 25 '13 at 14:50
  • 1
    There is no direct Guice integration for Jersey2 at present but it can be achieved using HK2 as a bridge see - https://hk2.java.net/guice-bridge/index.html – PiersyP Jul 25 '13 at 15:01
  • I know this is getting a bit old, but is the idea with this bridge to have a different ResourceConfig for using a different Guice module? (Say in the case of binding to mock implementations for testing.) – Myles Sep 27 '13 at 19:00
  • Updated website for HK2-Guice bridge: https://hk2.java.net/2.2.0-b22/guice-bridge.html – albogdano Oct 18 '13 at 17:31
4

There is a page at HK2 official about correct guice implementation: https://javaee.github.io/hk2/guice-bridge.html

You should create your Injector something like this:

  public class GuiceConfig extends ResourceConfig {

        @Inject
        public GuiceConfig(ServiceLocator serviceLocator) {
            this();
            GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
            GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
            guiceBridge.bridgeGuiceInjector(GuiceListener.createBiDirectionalGuiceBridge(serviceLocator));
        }

        public GuiceConfig() {
            packages(Injections.packages);
            addProperties(Injections.propertiesMap);
        }
    }

And code from the doc should be upgraded like:

   @WebListener
    public class GuiceListener extends GuiceServletContextListener {

        @Override
        public void contextInitialized(ServletContextEvent servletContextEvent) {
            Locale.setDefault(Locale.ENGLISH);
            super.contextInitialized(servletContextEvent);
        }

        public static volatile Injector injector = null;

        @Override
        protected Injector getInjector() {
            return injector;

        }

        @SuppressWarnings("unchecked")
        private static Module getModule() {
            return binder -> {
                Injections.singletonInterfaces.forEach((i, c) -> binder.bind(i).to(c).in(Scopes.SINGLETON));
                Injections.singletonClasses.forEach(c -> binder.bind(c).in(Scopes.SINGLETON));
            };
        }

        static synchronized Injector createBiDirectionalGuiceBridge(ServiceLocator serviceLocator) {

            return GuiceListener.injector = createBiDirectionalGuiceBridge(serviceLocator, getModule());
        }

    }

Using the maven dependency at your pom.xml

   <dependency>
        <groupId>org.glassfish.hk2</groupId>
        <artifactId>guice-bridge</artifactId>
        <version>2.3.0</version>
    </dependency>

https://github.com/phxql/jersey2-guice doesn't work with jersey 2.22 and guice 4.0.

Stefan Birkner
  • 21,766
  • 10
  • 52
  • 68
Globber
  • 555
  • 3
  • 13
  • 1
    The official bridge is horribly broken. See https://java.net/jira/browse/HK2-139 and https://java.net/jira/browse/JERSEY-1950 for more information. – Gili Jan 26 '16 at 22:23
1

This is a minimum working PoC which wires Jersey 2 and Guice together:

https://github.com/phxql/jersey2-guice

phXql
  • 157
  • 11
  • -1, this doesn't support injecting guice types into constructors. – Gili Aug 08 '14 at 09:02
  • In MyResource a TimeService is injected with Guice, see https://github.com/phxql/jersey2-guice/blob/master/src/main/java/de/mkammerer/poc/jersey2guice/jersey/MyResource.java#L17 – phXql Aug 11 '14 at 10:56
  • That doesn't make a difference. The HK2 bridge does not support constructor injection. – Gili Aug 17 '14 at 10:35
  • I don't get it, if you deploy the war to an application server, it's working. – phXql Aug 17 '14 at 15:24
1

I've already done in this sample:

https://github.com/jbescos/tododev

You have to register the class https://github.com/jbescos/tododev/blob/master/jersey2-guice/src/main/java/es/tododev/rest/ApplyGuiceContextFilter.java in your ResourceConfig, and the guice injector binded in an AbstractModule.

@Provider
@PreMatching
public class ApplyGuiceContextFilter implements ContainerRequestFilter, ContainerResponseFilter {

    @Inject
    public ApplyGuiceContextFilter(ServiceLocator serviceLocator, Injector injector) {
        GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);

        GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
        guiceBridge.bridgeGuiceInjector(injector);
    }

    @Override
    public void filter(final ContainerRequestContext requestContext) throws IOException {

    }

    @Override
    public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext responseContext) throws IOException {}
}  

This is the ResouceConfig:

public class RestConfig extends ResourceConfig {

    @Inject
    public RestConfig() {
        this(Guice.createInjector(new Module(){
            @Override
            public void configure(Binder arg0) {
                // TODO Auto-generated method stub
            }
        }));
    }

    // Test
    public RestConfig(Injector injector) {
        packages(ResourceSample.class.getPackage().getName());
        register(ApplyGuiceContextFilter.class);
        register(new LoggingFilter(Logger.getLogger(LoggingFilter.class.getName()), true));

        property(ServerProperties.TRACING, "ALL");
        register(new RestBinder(injector));
    }

    private static class RestBinder extends AbstractBinder{

        private final Injector injector;

        private RestBinder(Injector injector){
            this.injector = injector;
        }

        @Override
        protected void configure() {
            bind(injector).to(Injector.class);
        }

    }

}
mkobit
  • 34,772
  • 9
  • 135
  • 134
ravenskater
  • 484
  • 1
  • 4
  • 14
1

GWizard includes a module that gives you out-of-the-box integration between Jersey2 and Guice. Here's an example of a complete JAX-RS service:

public class Main {
    @Path("/hello")
    public static class HelloResource {
        @GET
        public String hello() {
            return "hello, world";
        }
    }

    public static class MyModule extends AbstractModule {
        @Override
        protected void configure() {
            bind(HelloResource.class);
        }
    }

    public static void main(String[] args) throws Exception {
        Guice.createInjector(new MyModule(), new JerseyModule()).getInstance(WebServer.class).startJoin();
    }
}

Note that this is based on the Squarespace jersey2-guice adapter, which may not function properly with future point releases of Jersey. GWizard also offers a RESTEasy JAX-RS module, which is preferred.

Here is a blog entry about this that might help: http://blorn.com/post/107397841765/guice-and-jersey-2-the-easy-way

mkobit
  • 34,772
  • 9
  • 135
  • 134
stickfigure
  • 12,641
  • 4
  • 30
  • 46
0

For those interested, there is a sample of guice/jersey integration available at https://github.com/mycom-int/jersey-guice-aop.

devlearn
  • 1,645
  • 2
  • 16
  • 28
  • 1
    It's not clear what you're doing here (especially because you talk about unidirectional injection but don't explain which direction you mean). You need a bi-directonal bridge because Jersey will always ask HK2 to inject (in which can you want HK2 to delegate to Guice) and on the flip side, when you ask Guice to inject an Object which happens to contain a Jersey type (e.g. UriInfo) you need Guice to delegate to HK2 for injection. In short: **a unidirectional bridge is not enough.** – Gili Mar 21 '14 at 22:10
  • Maybe to clarify : uni directional bridge is enough to inject Guice resources into Jersey. If you want to use AOP and mix Guice and HK2 then you definitely need the bi-directional bridge. – devlearn Mar 24 '14 at 10:24
  • You're going to have a very hard time not mixing Guice and HK2. I'll give a specific example: if you inject a Jersey resource using Guice but it references `UriInfo` then Guice will need to delegate to HK2 to get an instance (but won't be able to). – Gili Mar 24 '14 at 20:48
0

Here is an example using Embedded Jetty (it should probably work for Jetty server too)

jetty-jersey-HK2-Guice-boilerplate

If you are planning to use Guice for your application, all Guice components injected into Jersey need to be declared as a binding in the Guice config.

If you don't want to declare every binding in Guice config, there is an adapter here:

guice-bridge-jit-injector

Choi
  • 39
  • 2