users@jersey.java.net

Re: [Jersey] Cannot get injected a reference of a stateless EJB

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Mon, 23 Feb 2009 09:43:31 +0100

Hi Antonio,

JAX-RS 1.0 does not specify integration with EE (5 or 6) so the
following is not specified:

   1) injection of EE resources onto a resource or provider class; and/
or

   2) an EJB stateless session bean that is a resource or provider
class.

JAX-RS 1.1 does address the above, see the MR:

   http://jcp.org/aboutJava/communityprocess/maintenance/jsr311/311ChangeLog.html

   "An implementation MUST support use of stateless session beans as
root resource classes and providers in a Web
    application. JAX-RS annotations MAY be applied to a bean's local
interface or directly to a no-interface bean."

For resource or provider classes that are not of 2) we plan to support
1) by deferring to the specification formally known as Web Beans.

Having said that there are some ways you might be able to get what you
want working:

1) Jersey, in conjunction with Glassfish, supports EJB 3.0 stateless
session beans. It is necessary to annotate the local or
      remote interface with JAX-RS annotations and then register that
interface as a root resource class. I demoed this at
      Devoxx, see the following for the NetBeans project i used:

      http://blogs.sun.com/sandoz/entry/devoxx_slides_and_examples_for

      Also see the following for more details:

      https://jersey.dev.java.net/source/browse/*checkout*/jersey/tags/jersey-1.0.2/api/jersey/com/sun/jersey/spi/container/servlet/ServletContainer.html
#configure(com.sun.jersey.spi.container.servlet.WebConfig,
%20com.sun.jersey.api.core.ResourceConfig,
%20com.sun.jersey.spi.container.WebApplication)

      "Any root resource class in registered in the resource
configuration that is an interface is processed as follows. If the
       class is an interface and there exists a JNDI named object with
the fully qualified class name as the JNDI name then
       that named object is added as a singleton root resource and the
class is removed from the set of root resource classes."


2) Register an instance of an EJB obtained using JNDI. See the
following for more details:

     http://wikis.sun.com/display/Jersey/Overview+of+JAX-RS+1.0+Features#OverviewofJAX-RS1.0Features-DeployingaRESTfulWebservice

     For example:

     public class MyApplicaton extends Application {
         public Set<Object> getSingletons() {
             javax.naming.Context x = ...
             Object o = x.lookup( <name of EJB> );
             Set<Object> s = new HashSet<Object>();
             s.add(o);
             return s;
         }
     }


It is my understanding that you should be able to utilize 2) with the
EJB 3.1 war packaging style and the no-interface view. We worked with
the EJB spec lead to ensure that annotations will be carried over and
that a portable JNDI naming scheme can be utilized. Obviously this is
not currently the most ideal way, JAX-RS annotated EJB 3.1 beans
should get registered automatically for a compliant JAX-RS 1.1
application with EE 6, and the developer should not have to configure
anything.

Hope this helps,
Paul.


On Feb 21, 2009, at 7:21 PM, Antonio Goncalves wrote:

> Oh I forgot to say that I use the EJB 3.1 packaging style:
> everything is in the same war
>
> 2009/2/21 Antonio Goncalves <antonio.mailing_at_gmail.com>
> Hi,
>
> I have a JAX-RS BookResource that delegates all the database access
> to a stateless BookEJB and I have a JSF managed bean that also uses
> the same EJB. In JSF I get injected the reference of my EJB and I
> can get data (Book entity) out of the database. It works fine. But
> when I try to do the same thing with my resource and get injected a
> reference from my EJB, I get a NullPointerException.
>
> First my EJB was using the new EJB 3.1 style with no interface at
> all. I thought that could be the problem and introduced a local
> interface, but it doesn't work still.
>
> I'm using GlassFish V3b37.
>
> Any idea ?
> Thanks,
> Antonio
>
>
> BookResource
> ==========
>
> @Path("books")
> public class BookResource {
>
> @EJB
> private BookEJBLocal bookEJB;
>
> @GET
> @Path("{id}/")
> @Produces({"application/xml", "application/json"})
> public Book getBookById(@PathParam("id") Long id) {
>
> Book book = bookEJB.findBook(id);
> return book;
> }
>
> @GET @Produces({"application/xml", "application/json"})
> public List<Book> getAllBooks() {
> List<Book> books = bookEJB.findBooks();
> return books;
> }
> }
>
>
> BookEJB
> =======
> @Stateless
> public class BookEJB implements BookEJBLocal {
>
> @PersistenceContext(unitName = "chapter15PU")
> private EntityManager em;
>
> public List<Book> findBooks() {
> Query query = em.createNamedQuery("findAllBooks");
> return query.getResultList();
> }
>
> public Book findBook(Long id) {
> return em.find(Book.class, id);
> }
> }
>
>
> BookEJBLocal
> ===========
> @Local
> public interface BookEJBLocal {
> List<Book> findBooks();
> Book createBook(Book book);
> Book findBook(Long id);
> }
>
>
> The Book entity is annotated with JPA and JAXB
> ===================================
> @XmlRootElement
> @Entity
> @NamedQuery(name = "findAllBooks", query = "SELECT b FROM Book b")
> public class Book {
>
> @Id @GeneratedValue
> private Long id;
> private String title;
> private Float price;
> private String description;
> private String isbn;
> private Integer nbOfPage;
> private Boolean illustrations;
> // getters and setters
> }
>
>
> Stack Trace
> =========
> GRAVE: StandardWrapperValve[Jersey Web Application]: PWC1406:
> Servlet.service() for servlet Jersey Web Application threw exception
> java.lang.NullPointerException
> at
> com
> .apress
> .javaee6.chapter15.ex99.BookResource.getBookById(BookResource.java:40)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun
> .reflect
> .NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at
> sun
> .reflect
> .DelegatingMethodAccessorImpl
> .invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at
> com
> .sun
> .jersey.server.impl.model.method.dispatch.EntityParamDispatchProvider
> $TypeOutInvoker._dispatch(EntityParamDispatchProvider
> .java:138)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .model
> .method
> .dispatch
> .ResourceJavaMethodDispatcher
> .dispatch(ResourceJavaMethodDispatcher.java:67)
> at
> com
> .sun
> .jersey
> .server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:124)
> at
> com
> .sun
> .jersey
> .server
> .impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:111)
> at
> com
> .sun
> .jersey
> .server
> .impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:71)
> at
> com
> .sun
> .jersey
> .server
> .impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:111)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .uri
> .rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:63)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl._handleRequest(WebApplicationImpl.java:555)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:514)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:505)
> at
> com
> .sun
> .jersey
> .spi
> .container.servlet.ServletContainer.service(ServletContainer.java:359)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:
> 847)
> at
> org
> .apache
> .catalina
> .core
> .ApplicationFilterChain.servletService(ApplicationFilterChain.java:
> 465)
> at
> org
> .apache
> .catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:
> 306)
> at
> org
> .apache
> .catalina.core.StandardContextValve.invoke(StandardContextValve.java:
> 190)
> at
> org
> .apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:
> 656)
> at
> com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
> at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke
> (PESessionLockingStandardPipeline.java:98)
> at
> org
> .apache
> .catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
> at
> org
> .apache
> .catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:346)
> at
> org
> .apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:
> 244)
> at
> com
> .sun
> .enterprise
> .v3.services.impl.ContainerMapper.service(ContainerMapper.java:181)
> at
> com
> .sun
> .grizzly
> .http.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:
> 646)
> at
> com
> .sun
> .grizzly
> .http.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:568)
> at
> com
> .sun
> .grizzly.http.DefaultProcessorTask.process(DefaultProcessorTask.java:
> 821)
> at
> com
> .sun
> .grizzly
> .http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:153)
> at
> com
> .sun
> .enterprise
> .v3
> .services
> .impl
> .GlassfishProtocolChain
> .executeProtocolFilter(GlassfishProtocolChain.java:71)
> at
> com
> .sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:
> 103)
> at
> com
> .sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:
> 89)
> at
> com
> .sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
> at
> com
> .sun
> .grizzly
> .ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:67)
> at
> com
> .sun
> .grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:56)
> at java.util.concurrent.FutureTask
> $Sync.innerRun(FutureTask.java:303)
> at java.util.concurrent.FutureTask.run(FutureTask.java:138)
> at java.util.concurrent.ThreadPoolExecutor
> $Worker.runTask(ThreadPoolExecutor.java:886)
> at java.util.concurrent.ThreadPoolExecutor
> $Worker.run(ThreadPoolExecutor.java:908)
> at java.lang.Thread.run(Thread.java:619)
>
>
>
> --
> --
> Antonio Goncalves (antonio.goncalves_at_gmail.com)
> Software architect
>
> Paris JUG leader : www.parisjug.org
> Web site : www.antoniogoncalves.org
> Blog: jroller.com/agoncal
> LinkedIn: www.linkedin.com/in/agoncal