Kohei Nozaki's blog 

Lean example of Tomcat 8 + Guice 4 + Jersey 2.19


Posted on Wednesday Aug 05, 2015 at 02:36PM in Technology


Jersey is the RI of JAX-RS. in this entry, I introduce you how to use Jersey 2.19 with Guice 4 on Tomcat 8. it looks like there are some issues exist as follows but thanks to https://github.com/Squarespace/jersey2-guice , I’ve succeeded to use them anyway.

The entire project which based on Maven can be obtained from My GitHub repository.

Dependencies

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey</groupId>
            <artifactId>jersey-bom</artifactId>
            <version>2.19</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
    </dependency>
    <dependency>
        <groupId>com.google.inject</groupId>
        <artifactId>guice</artifactId>
        <version>4.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.inject.extensions</groupId>
        <artifactId>guice-servlet</artifactId>
        <version>4.0</version>
    </dependency>
    <dependency>
        <groupId>com.squarespace.jersey2-guice</groupId>
        <artifactId>jersey2-guice</artifactId>
        <version>0.10</version>
    </dependency>
</dependencies>

web.xml

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>guice.tomcat.jersey</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/webapi/*</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>guice.tomcat.MyJerseyGuiceServletContextListener</listener-class>
    </listener>

    <filter>
        <filter-name>guiceFilter</filter-name>
        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>guiceFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

MyJerseyGuiceServletContextListener.java

In this example, we use the servlet context listener named JerseyGuiceServletContextListener which comes from jersey2-guice artifact as parent class.

public class MyJerseyGuiceServletContextListener extends JerseyGuiceServletContextListener {
    @Override
    protected List<? extends Module> modules() {
        return Collections.singletonList(new ServletModule() {
            @Override
            protected void configureServlets() {
                bind(MyService.class).to(MyServiceImpl.class);
            }
        });
    }
}

Service class

We use very simple pair of an interface and implementation that creates a simple greeting message, which used in a past entry so omitted for simplicity.

MyResource.java

This is an simple implementation of JAX-RS resource class. placed under guice.tomcat.jersey package. the preceding service class named MyService will be injected by @javax.inject.Inject annotation.

@Path("myresource")
public class MyResource {

    @Inject
    private MyService myService;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getIt() {
        return myService.hello("Jersey");
    }
}

Test run

$ curl http://localhost:8080/webapi/myresource
Hello, Jersey



Comments:

Hi
i have tried this example and getting same error:

NoSuchMethodError: com.google.inject.binder.AnnotatedBindingBuilder.toProvider(Ljavax/inject/Provider;)Lcom/google/inject/binder/ScopedBindingBuilder

Posted by Luger on December 09, 2015 at 03:09 PM JST #


This example is lean but not useful. Not working and intended for people knew guice already. Thumbs down.

Posted by bob on April 26, 2016 at 05:47 PM JST #


Folks, could you give some of more information so I can explore the cause (e.g. could you share file listing of your WAR which failed to run?) ?

Could you try again with following procedure? I've just confirmed that my example is working fine as I expected.

1. git clone https://github.com/lbtc-xxx/guice-jersey-tomcat.git
2. cd guice-jersey-tomcat; mvn clean package
3. cp target/guice-tomcat-1.0-SNAPSHOT.war $CATALINA_HOME/webapps
4. *** wait until deployment is done ***
5. curl http://localhost:8080/guice-tomcat-1.0-SNAPSHOT/webapi/myresource

As for Luger's situation, I guess you have multiple jars of different version of Guice, maybe they were differ in the build time and runtime.

Posted by Kohei Nozaki on April 30, 2016 at 10:37 AM JST #


FYI: This is the listing of library jars of the WAR which works fine for me. make sure your WAR contains exactly the same library jars (versions as well) as this one:

$ ls guice-tomcat-1.0-SNAPSHOT/WEB-INF/lib/ | cat
aopalliance-1.0.jar
aopalliance-repackaged-2.4.0-b25.jar
guava-16.0.1.jar
guice-4.0.jar
guice-multibindings-4.0.jar
guice-servlet-4.0.jar
hk2-api-2.4.0-b25.jar
hk2-locator-2.4.0-b25.jar
hk2-utils-2.4.0-b25.jar
javassist-3.18.1-GA.jar
javax.annotation-api-1.2.jar
javax.inject-1.jar
javax.inject-2.4.0-b25.jar
javax.ws.rs-api-2.0.1.jar
jersey-client-2.19.jar
jersey-common-2.19.jar
jersey-container-servlet-2.19.jar
jersey-container-servlet-core-2.19.jar
jersey-guava-2.19.jar
jersey-media-jaxb-2.19.jar
jersey-server-2.19.jar
jersey2-guice-0.10.jar
jsr305-3.0.0.jar
osgi-resource-locator-1.0.1.jar
slf4j-api-1.7.12.jar
validation-api-1.1.0.Final.jar

Hope this helps,

Posted by Kohei on April 30, 2016 at 10:20 PM JST #


I confirm that's work fine!!!

Posted by piripicchio on June 03, 2016 at 09:14 PM JST #


Hi,

Why doesn't work on glassfish 4 or 5?
I tried to deploy .war on glassfish server but doesn't work.
This is the error:

Error occurred during deployment: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: java.lang.IllegalArgumentException: javax.servlet.ServletException: com.sun.enterprise.container.common.spi.util.InjectionException: Error creating managed object for class: class guice.tomcat.MyJerseyGuiceServletContextListener. Please see server.log for more details.

Have you any idea?

Posted by Teodor on February 22, 2018 at 07:05 AM JST #


Hi Teodor, I have no wonder that my example doesn’t work on a full fledged Java EE container (GlassFish) because it has its own JAX-RS and CDI implementations out of box. I recommend you not to use Guice and Jersey this way but to use its out of box implementations.

Posted by Kohei on February 22, 2018 at 10:11 AM JST #


I've been stressing over getting a Jersey webapp spun up, and your project finally got me where I wanted to be.

The only problem I had was that I was getting NoClassDefFoundError: javax/xml/bind/JAXBException. It turns out that it's because I'm using Java 11, which seems to have removed necessary modules for JAX-B.

I found the fix here: https://stackoverflow.com/a/43574427

So, if you'd like to update your code to be compatible with Java 11, simply add these two dependencies:

<!-- API, java.xml.bind module -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.2</version>
</dependency>

<!-- Runtime, com.sun.xml.bind module -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
</dependency>

Again, thanks so much!

Posted by Patrick on August 14, 2020 at 11:01 AM JST #


Leave a Comment

HTML Syntax: NOT allowed