@Resource not injected in Jersey resource

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

@Resource not injected in Jersey resource

Francois Ross
Hi,

How come @Resource annotations get picked up by servlets but not by Jersey resources?
 
I've been struggling to inject a DataSource via @Resource for a few hours with no success so far (I got lost along the way reading about jersey CDI, Weld, HK2, ...). I've set up a small Eclipse project on GitHub showing the behavior (see here).

I'm using:
  • Tomcat 7 (dynamic web module version 3.0).
  • a H2 data source configured in META-INF/context.xml
  • jersey-container-servlet 2.23.1
Any help or explanation would be greatly appreciated (I'm a desktop/embedded software developer).

import javax.annotation.Resource;
import javax.sql.DataSource;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/")
public class MyResource {
    
    @Resource(name = "jdbc/myDatabase")
    private DataSource _dataSource;
    
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public Response doGet() {
        return Response
                .ok()
                .entity("jersey -> dataSource? " + (_dataSource != null))    // jersey -> dataSource? false
.build(); } }

import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

@WebServlet(urlPatterns = { "/servlet" })
public class MyServlet extends HttpServlet {

    @Resource(name = "jdbc/myDatabase")
    private DataSource _dataSource;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            _dataSource.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }

        resp.setContentType("text/plain");
        resp.getWriter().write("servlet -> dataSource? " + (_dataSource != null));    // servlet -> dataSource? true
    }
}
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: @Resource not injected in Jersey resource

Pavel Bucek-2

Hi Francois,

@Resource is not injected, since Jersey doesn't know that you want this bean to be managed by the container.

You can try to mark your resource "MyResource" with @ManagedBean - then @Resource fields should be injected.

See managed beans webapp example:

https://github.com/jersey/jersey/tree/927b4d0605aeb119d15e9623dab65c8aec2c8e20/examples/managed-beans-webapp

, concretely this class:

https://github.com/jersey/jersey/blob/927b4d0605aeb119d15e9623dab65c8aec2c8e20/examples/managed-beans-webapp/src/main/java/org/glassfish/jersey/examples/managedbeans/resources/ManagedBeanSingletonResource.java

Hope it helps,
Pavel

On 11/07/16 23:35, Francois Ross wrote:
Hi,

How come @Resource annotations get picked up by servlets but not by Jersey resources?
 
I've been struggling to inject a DataSource via @Resource for a few hours with no success so far (I got lost along the way reading about jersey CDI, Weld, HK2, ...). I've set up a small Eclipse project on GitHub showing the behavior (see here).

I'm using:
  • Tomcat 7 (dynamic web module version 3.0).
  • a H2 data source configured in META-INF/context.xml
  • jersey-container-servlet 2.23.1
Any help or explanation would be greatly appreciated (I'm a desktop/embedded software developer).

import javax.annotation.Resource;
import javax.sql.DataSource;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/")
public class MyResource {
    
    @Resource(name = "jdbc/myDatabase")
    private DataSource _dataSource;
    
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public Response doGet() {
        return Response
                .ok()
                .entity("jersey -> dataSource? " + (_dataSource != null))    // jersey -> dataSource? false
                .build();
    }
}

              
import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

@WebServlet(urlPatterns = { "/servlet" })
public class MyServlet extends HttpServlet {

    @Resource(name = "jdbc/myDatabase")
    private DataSource _dataSource;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            _dataSource.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }

        resp.setContentType("text/plain");
        resp.getWriter().write("servlet -> dataSource? " + (_dataSource != null));    // servlet -> dataSource? true
    }
}

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: @Resource not injected in Jersey resource

Francois Ross
Thanks alot.

I had a look at the example and gave it a try with no luck so far. My project is probably missing some dependencies (the exact dependencies are not easy to figure out from the pom.xml files... I'm also not using a full Java EE profile).

On Mon, Jul 11, 2016 at 6:24 PM, Pavel Bucek <[hidden email]> wrote:

Hi Francois,

@Resource is not injected, since Jersey doesn't know that you want this bean to be managed by the container.

You can try to mark your resource "MyResource" with @ManagedBean - then @Resource fields should be injected.

See managed beans webapp example:

https://github.com/jersey/jersey/tree/927b4d0605aeb119d15e9623dab65c8aec2c8e20/examples/managed-beans-webapp

, concretely this class:

https://github.com/jersey/jersey/blob/927b4d0605aeb119d15e9623dab65c8aec2c8e20/examples/managed-beans-webapp/src/main/java/org/glassfish/jersey/examples/managedbeans/resources/ManagedBeanSingletonResource.java

Hope it helps,
Pavel


On 11/07/16 23:35, Francois Ross wrote:
Hi,

How come @Resource annotations get picked up by servlets but not by Jersey resources?
 
I've been struggling to inject a DataSource via @Resource for a few hours with no success so far (I got lost along the way reading about jersey CDI, Weld, HK2, ...). I've set up a small Eclipse project on GitHub showing the behavior (see here).

I'm using:
  • Tomcat 7 (dynamic web module version 3.0).
  • a H2 data source configured in META-INF/context.xml
  • jersey-container-servlet 2.23.1
Any help or explanation would be greatly appreciated (I'm a desktop/embedded software developer).

import javax.annotation.Resource;
import javax.sql.DataSource;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/")
public class MyResource {
    
    @Resource(name = "jdbc/myDatabase")
    private DataSource _dataSource;
    
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public Response doGet() {
        return Response
                .ok()
                .entity("jersey -> dataSource? " + (_dataSource != null))    // jersey -> dataSource? false
                .build();
    }
}

              
import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

@WebServlet(urlPatterns = { "/servlet" })
public class MyServlet extends HttpServlet {

    @Resource(name = "jdbc/myDatabase")
    private DataSource _dataSource;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            _dataSource.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }

        resp.setContentType("text/plain");
        resp.getWriter().write("servlet -> dataSource? " + (_dataSource != null));    // servlet -> dataSource? true
    }
}


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: @Resource not injected in Jersey resource

Francois Ross
Got it working by using the dependencies listed in https://github.com/jersey/jersey/blob/2.23.1/examples/cdi-webapp/pom.xml (see tomcat-packaging). Thank you again Pavel. I updated my small proof of concept in case someone stumble on this (see github here).

Jul 12, 2016 10:45:17 PM org.jboss.weld.environment.servlet.EnhancedListener onStartup
INFO: WELD-ENV-001008: Initialize Weld using ServletContainerInitializer
Jul 12, 2016 10:45:17 PM org.jboss.weld.bootstrap.WeldStartup <clinit>
INFO: WELD-000900: 2.3.5 (Final)
Jul 12, 2016 10:45:18 PM org.jboss.weld.bootstrap.WeldStartup startContainer
INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
Jul 12, 2016 10:45:18 PM org.jboss.weld.event.ExtensionObserverMethodImpl checkRequiredTypeAnnotations
INFO: WELD-000411: Observer method [BackedAnnotatedMethod] private org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider.processAnnotatedType(@Observes ProcessAnnotatedType) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
Jul 12, 2016 10:45:19 PM org.jboss.weld.environment.tomcat.TomcatContainer initialize
INFO: WELD-ENV-001100: Tomcat 7+ detected, CDI injection will be available in Servlets, Filters and Listeners.
Jul 12, 2016 10:45:20 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Jul 12, 2016 10:45:20 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Jul 12, 2016 10:45:20 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 5124 ms
Loading...