0

Have a little problem at using CDI in a Rest Service:

Created a J2EE 7 Dynamic Web Project with the following file TestRessource.java :

@Path("/testpath")
public class TestRessource{
@Inject IDataBase db;
@GET
@Produces("text/html")
public Response getElements() {
    return Response.status(200).entity("Items").build();
}

If i include the line '@Inject IDataBase db', which should inject a dummy database class, i am not able to call the page localhost:8080/testpath in my browser. It ends up at a couple of exception stacks. The first one is:

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=IDataBase,parent=TestRessource,qualifiers={},position=-1,optional=false,self=false,unqualified=null,1686223016)

So it seems, that he can not find the files, that should be injected.

DataBase.java looks like:

public class Database implements IDataBase {

    private Map<String, Long> numbers; // Dummy data

    public Database() {
        numbers = new HashMap<>();
    }

    public String getItems() {
        return (new Gson()).toJson(numbers);
    }

}

IDataBase.java looks like:

public interface IDataBase {
    String getItems();
}

My pom.xml looks like:

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>en.testpackage</groupId>
  <artifactId>mytestproject</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>mytestprojectMavenWebapp</name>
  <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.bundles</groupId>
            <artifactId>jaxrs-ri</artifactId>
            <version>2.13</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers.glassfish</groupId>
            <artifactId>jersey-gf-cdi</artifactId>
            <version>2.14</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.weld.servlet</groupId>
            <artifactId>weld-servlet</artifactId>
            <version>2.4.7.Final</version>
        </dependency>

    </dependencies>

  <build>
    <finalName>mytestproject</finalName>

     <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.tomcat.maven</groupId>
          <artifactId>tomcat7-maven-plugin</artifactId>
          <version>2.1</version>
          <configuration>
            <path>/</path>
          </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>exec-war-only</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
      </plugins>
    </pluginManagement>

    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
      </plugin>

      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>

    </plugins>
  </build>
</project>

Here are the exception stacks:

type Exception report

message A MultiException has 3 exceptions. They are:

description The server encountered an internal error that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: A MultiException has 3 exceptions.  They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=IDataBase,parent=TestRessource,qualifiers={@javax.inject.Named(value=db)},position=-1,optional=false,self=false,unqualified=null,256127442)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of en.testpackage.resource.TestRessource errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on en.testpackage.resource.TestRessource

    org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:393)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)

root cause

A MultiException has 3 exceptions.  They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=IDataBase,parent=TestRessource,qualifiers={@javax.inject.Named(value=db)},position=-1,optional=false,self=false,unqualified=null,256127442)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of en.testpackage.resource.TestRessource errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on en.testpackage.resource.TestRessource

    org.jvnet.hk2.internal.Collector.throwIfErrors(Collector.java:88)
    org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:252)
    org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:360)
    org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:461)
    org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:160)
    org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2268)
    org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:690)
    org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:655)
    org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:169)
    org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:185)
    org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
    org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:115)
    org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:115)
    org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:115)
    org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:94)
    org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:63)
    org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
    org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:263)
    org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:297)
    org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:254)
    org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1030)
    org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:373)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)

root cause

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=IDataBase,parent=TestRessource,qualifiers={@javax.inject.Named(value=db)},position=-1,optional=false,self=false,unqualified=null,256127442)
    org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:74)
    org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:214)
    org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:237)
    org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:360)
    org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:461)
    org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:160)
    org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2268)
    org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:690)
    org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:655)
    org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:169)
    org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:185)
    org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
    org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
    org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:115)
    org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:115)
    org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:115)
    org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:94)
    org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:63)
    org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
    org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:263)
    org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:297)
    org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:254)
    org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1030)
    org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:373)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)

note The full stack trace of the root cause is available in the Apache Tomcat/7.0.37 logs.

So, if i delete the @Inject line, the rest service works fine, and i am able to load this page via a browser (but of course the object db is not injected)

I have already added an empty beans.xml in webapp/WEB-INF.

Is there anything that is missing to be able to use CDI here? Or is there anything else that i did not mentioned in the context of CDI+RestService?

Alex
  • 161
  • 1
  • 13

1 Answers1

0

So after many hours of experimenting, i have found a working solution:

My pom.xml looks now like:

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>en.testpackage</groupId>
    <artifactId>mytestproject</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>mytestprojectMavenWebapp</name>
    <dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.1</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.weld.servlet</groupId>
            <artifactId>weld-servlet</artifactId>
            <version>2.4.7.Final</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.ext.cdi</groupId>
            <artifactId>jersey-cdi1x</artifactId>
            <version>2.27</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>2.27</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.inject</groupId>
            <artifactId>jersey-hk2</artifactId>
            <version>2.27</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>mytestproject</finalName>

        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.1</version>
                    <configuration>
                        <path>/</path>
                    </configuration>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>exec-war-only</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>

        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <!-- more plugins e.g. shade plugin for my purpose -->

        </plugins>
    </build>
</project>

My src/main/webapp/WEB-INF/web.xml looks like:

   <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>JerseyRESTService</servlet-name>
            <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
            <init-param>
                <param-name>jersey.config.server.provider.packages</param-name>
                <param-value>com.testpackage.resource</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>JerseyRESTService</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
        <listener>
            <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
        </listener>
        <resource-env-ref>
            <resource-env-ref-name>BeanManager</resource-env-ref-name>
            <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
        </resource-env-ref>
    </web-app>

In src/main/resources/META-INF/beans.xml i have:

<?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>

In src/main/webapp/META-INF/context.xml i have:

<Context>
   <Resource name="BeanManager"
      auth="Container"
      type="javax.enterprise.inject.spi.BeanManager"
      factory="org.jboss.weld.resources.ManagerObjectFactory"/>
</Context>

With this combination i am able to avoid the exception stacks and i guess based on dependency jersey-cdi1x HK2 and Weld are able to "communicate" to each other.

In com.testpackage.resource i have multiple classes containing REST-methods.

I hope i will offer a working (update-to-date) solution for other users having all these exception problems.

The intention is to create a uber-jar-file containing Tomcat7 offering a REST-Service and using CDI based on Weld.

Alex
  • 161
  • 1
  • 13