users@jersey.java.net

[Jersey] Getting confused with EJB injection

From: Antonio Goncalves <antonio.mailing_at_gmail.com>
Date: Wed, 19 Jan 2011 23:29:52 +0100

Hi all,

I have a simple EJB 3.1 with no interface (ItemEJB) that does access to the
database using an Entity.

@Stateless
public class ItemEJB {

    @PersistenceContext
    private EntityManager em;

    public Book getBook(Long id) {
        return em.find(Book.class, id);
    }
}


In front of this EJB I have a Servlet 3.0 that injects the EJB and uses it :

@WebServlet(urlPatterns = "/itemServlet")
public class ItemServlet extends HttpServlet {

    *_at_EJB // or @Inject with CDI work fine*
   * private ItemEJB itemEJB;*

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

        // Creates an instance of book
        Book book = new Book("title", 999.99F, "description", 666, false,
"english", "scifi");
        *itemEJB.createBook(book);*

        resp.setContentType("text/html");
        PrintWriter out = resp.getWriter();
        out.println("<h1>====== All books</h1>");
        List<Book> books = *itemEJB.findAllBooks()*;
        for (Book b : books) {
            out.println("==> " + b + "<br/>");
        }
}

As you can see, I can either inject the EJB using the good old @EJB or the
new @Inject (with the famous empty beans.xml file). In both cases I manage
to make this servlet work in GlassFish 3.1-b37 and 3.0.1-b22.


If I do the same with a REST service, neither case works, I always get a NPE
(with @EJB, @Inject, both versions of GlassFish... I always get a NPE). So
the following code never works :

@Path("/items")
public class ItemResource {

    *_at_EJB // or @Inject with CDI produces a NPE*
    *private ItemEJB itemEJB;*

    @GET
    @Path("/{bookKey}")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Book getBook(@PathParam("bookKey") Long id) {
        return *itemEJB.getBook(id)*;
    }
}

Then, if I turn this REST service into an EJB by adding a
@Statelessannotation as follow :

@Path("/items")
*_at_Stateless*
public class ItemResource {

    *_at_EJB // or @Inject with CDI*
    *private ItemEJB itemEJB;*
* ...*
}

the @EJB and @Inject work with both GlassFish 3.1-b37 and 3.0.1-b22.

I have read several posts about this (including old ones :
http://blogs.sun.com/sandoz/entry/ejb_injection) but I'm still confused. Can
I inject an EJB into a REST service that is not itself an EJB (i.e. it is
just annotated with @Path).

Thanks

--
Antonio Goncalves (antonio.goncalves_at_gmail.com)
Software architect
Web site : www.antoniogoncalves.org
Blog: agoncal.wordpress.com
Feed: feeds2.feedburner.com/AntonioGoncalves
Paris JUG leader : www.parisjug.org
LinkedIn: www.linkedin.com/in/agoncal