carpics
carpics

Reputation: 2282

How to configure Tomcat 9 with CDI and JAX-RS, Java EE7?

I am trying to implement simple java Rest application and deploy it to Tomcat server. (Tomcat is required, so Tomee is not an option)

This is structure of my project:

enter image description here

Content of Root pom.xml:

<?xml version="1.0" encoding="UTF-8"?>

    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>org.example</groupId>
      <artifactId>tomcat-project</artifactId>
      <version>1.0-SNAPSHOT</version>
      <modules>
        <module>tomcat-rest</module>
        <module>tomcat-app</module>
      </modules>
      <packaging>pom</packaging>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
      </properties>
    
      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
          </dependency>
        </dependencies>
      </dependencyManagement>
    
      <dependencies>
        <dependency>
          <groupId>javax</groupId>
          <artifactId>javaee-api</artifactId>
          <scope>provided</scope>
        </dependency>
      </dependencies>
    
      <build>
        <resources>
          <resource>
            <directory>src/main/resources</directory>
            <includes>
              <include>META-INF/*</include>
            </includes>
            <filtering>true</filtering>
          </resource>
        </resources>
      </build>
    </project>

Content of tomcat-rest pom.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <parent>
        <artifactId>tomcat-project</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
      </parent>
      <modelVersion>4.0.0</modelVersion>
    
      <artifactId>tomcat-rest</artifactId>
    </project>

Content of tomcat-app pom.xml:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <artifactId>tomcat-project</artifactId>
    <groupId>org.example</groupId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>tomcat-app</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.example</groupId>
      <artifactId>tomcat-rest</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>tomcat-app</finalName>

    <plugins>
      <plugin>
        <groupId>org.codehaus.cargo</groupId>
        <artifactId>cargo-maven2-plugin</artifactId>
        <version>1.7.13</version>
        <configuration>
          <container>
            <containerId>tomcat9x</containerId>
            <type>embedded</type>
          </container>
          <deployables>
            <deployable>
              <properties>
                <context>tomcat-app</context>
              </properties>
            </deployable>
          </deployables>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.openejb.maven</groupId>
        <artifactId>tomee-maven-plugin</artifactId>
        <version>1.7.1</version>
        <configuration>
          <tomeeVersion>1.7.1</tomeeVersion>
          <tomeeClassifier>plus</tomeeClassifier>
          <debugPort>7000</debugPort>
          <tomeeHttpPort>8080</tomeeHttpPort>
          <args>-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7000</args>
          <debug>false</debug>
          <reloadOnUpdate>true</reloadOnUpdate>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Content of web.xml:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
</web-app>

Content of beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans 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/beans_1_1.xsd"
       bean-discovery-mode="all">
</beans>

Content of RestApplication.java:

package org.example.rest;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("rest")
public class RestApplication extends Application {
}

Content of TestBean.java:

package org.example.rest;

import javax.ejb.Stateless;

@Stateless
public class TestBean {
    public String test() {
        return "Test Bean";
    }
}

Content of TestResource.java:

package org.example.rest;

import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/test")
@Stateless
public class TestResource {

    @Inject TestBean testBean;
    @GET
    public String test() {
        return testBean.test();
    }
}

As you see in tomee-app pom.xml I have configured maven plugins tomee-maven-plugin and cargo-maven2-plugin (with container set to tomcat9x) as this one the only maven plugin I found to run Tomcat 9.

With Tomee everything works fine, Jax-Rs is running and Injection of Test bean is working fine.

But with Tomcat I was not able to get CDI at least working. I tried several options found on Tomcat, OpenWebBeans, Apache CXF etc.. and I always end up with ether Jax-Rs not running on Injection doesn't work.

I didn't post errors which I was getting as I tried so many things and end up with bunch of different errors.

I would prefer to use OpenWebBeans and Apache CXF as Tomee use them but was not able to find any working instructions so far.

I tried to follow these instructions to get OpenWebBeans running with Tomcat, and also Glassfish Jersey Containers but I am getting errors on Injection of TestBean.

Upvotes: 2

Views: 2124

Answers (1)

You need additional dependencies, JAX-RS implementation and CDI implementation.

For example:

<dependency>
  <!-- https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/modules-and-dependencies.html#servlet-app-general -->
  <groupId>org.glassfish.jersey.containers</groupId>
  <artifactId>jersey-container-servlet</artifactId>
  <version>${jersey.version}</version>
</dependency>
<dependency>
  <groupId>org.glassfish.jersey.inject</groupId>
  <artifactId>jersey-hk2</artifactId>
  <version>${jersey.version}</version>
</dependency>
<dependency>
  <!-- https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/cdi.support.html#cdi.support.existing.containers -->
  <groupId>org.glassfish.jersey.ext.cdi</groupId>
  <artifactId>jersey-cdi1x</artifactId>
  <version>${jersey.version}</version>
</dependency>
<dependency>
  <!-- https://docs.jboss.org/weld/reference/latest-3.1/en-US/html/environments.html#weld-servlet -->
  <groupId>org.jboss.weld.servlet</groupId>
  <artifactId>weld-servlet-core</artifactId>
  <version>${weld.version}</version>
</dependency>

Then, replace javax.ejb.Stateless annotation to javax.enterprise.context.RequestScoped, because javax.ejb.Stateless annotation is not CDI spec, but EJB spec.


complete diff

Upvotes: 2

Related Questions