How to use guice-servlet with Jersey 2.0?
Asked Answered
H

8

30

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

Hollis answered 24/6, 2013 at 21:24 Comment(2)
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 #16217259 for more information.Hartzke
@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.Hollis
H
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.

Hollis answered 17/8, 2014 at 10:36 Comment(3)
I just whipped up a quick example using jersey2-guice with embedded Jetty at github.com/hansenc/jersey2-guice-example and it seems to work as advertised.Hepburn
There are problems with Jersey 2.20+. 2.19 works fine. Issue github.com/Squarespace/jersey2-guice/issues/32 Good example nailedtothex.org/roller/kyle/entry/lean-example-of-tomcat-82Perquisite
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+.Isometropia
H
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.

Huang answered 25/7, 2013 at 14:3 Comment(6)
Only works with Glassfish. A more generic example is needed that will work on Tomcat, Jetty, etc.Shrovetide
Hi mjaggard, I'm not sure I understand your point, in the example posted I have used jetty not glassfish?Huang
Sorry, I guess I got confused by the use of HK2. Why is that being used?Shrovetide
There is no direct Guice integration for Jersey2 at present but it can be achieved using HK2 as a bridge see - hk2.java.net/guice-bridge/index.htmlHuang
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.)Graiggrail
Updated website for HK2-Guice bridge: hk2.java.net/2.2.0-b22/guice-bridge.htmlAlbaalbacete
I
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.

Insignificant answered 26/1, 2016 at 15:23 Comment(1)
The official bridge is horribly broken. See java.net/jira/browse/HK2-139 and java.net/jira/browse/JERSEY-1950 for more information.Hollis
B
1

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

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

Baylor answered 7/8, 2014 at 7:23 Comment(4)
-1, this doesn't support injecting guice types into constructors.Hollis
In MyResource a TimeService is injected with Guice, see github.com/phxql/jersey2-guice/blob/master/src/main/java/de/…Baylor
That doesn't make a difference. The HK2 bridge does not support constructor injection.Hollis
I don't get it, if you deploy the war to an application server, it's working.Baylor
A
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);
        }

    }

}
Arbitrament answered 14/8, 2014 at 13:34 Comment(0)
R
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

Riorsson answered 7/1, 2015 at 10:34 Comment(0)
S
0

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

Sumach answered 21/3, 2014 at 9:40 Comment(3)
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.Hollis
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.Sumach
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).Hollis
C
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

Condign answered 3/7, 2014 at 19:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.