Cant inject Bean class into Restfull WebService (JAX-RS)

12,121

Solution 1

The @EJB annotation is not supposed to work for all objects.

For this to work you need to use CDI, so substitute the @EJB with @Inject and your bean will be correctly injected.

See also: Inject an EJB into JAX-RS (RESTful service)

EDIT:

Also be sure to add beans.xml to every jar/war archive containing classes you want to inject or be injected. It goes into META-INF for jars and WEB-INF for wars.

Your REST application class packaget.Rest should extend javax.ws.rs.core.Application as in:

@ApplicationPath("/root-path") 
public class Rest extends Application 
{ 
}

And according to the documentation here on JBoss 6.1 REST and CDI should work out of the box. If you specify the org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher and the org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap you are probably messing up the RestEasy/CDI classloading.

So your web.xml should look as:

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee java.sun.com/xml/ns/javaee/…"> 
</web-app> 

Anyway, I pushed a working example on github

Solution 2

You should add /src/main/resources/META-INF/beans.xml. This will enable injection.

Solution 3

I has similar issue, for me the problem was creating my RESTful bean on my own with constructor, which was dumb while using EJBs and @EJB injection:

PROBLEM:

@ApplicationPath("/")
public class RestApplication extends Application {
    private Set<Object> singletons = new HashSet<Object>();
    public RestApplication() {
        singletons.add(new RestService());
    }
    @Override
    public Set<Object> getSingletons() {
        return singletons;
    }
}

SOLUTION:

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

Hope it might save sb's time.

Share:
12,121
user2377971
Author by

user2377971

Updated on June 04, 2022

Comments

  • user2377971
    user2377971 almost 2 years

    I'm trying to save data acquired by Rest web service to database using hibernate/persistence. In one of my web modules i implemented that service. Database ejb connector is placed in EJB module. They are parts of EAR application. Every time when i call pb.addDevice() im getting java.lang.NullPointerException when puting proper url with params in browser(worked till i wanted to save it to Database). Can't find what is wrong with it. I'm using jboss 6.1.0 Final.

    tried answer of Dependency injection in restful WS

    and after following it step by step im alse getting nullpointer also

    PS. when i changed from

    @EJB
    PersistenceBean pb; 
    

    to

    PersistenceBean pb = new PersistenceBean();
    

    i got null pointer on EntityManager em = emf.createEntityManager();

    code:

    @Stateless
    @Path("/RestService")
    public class RestPush  {
    
    @EJB
    PersistenceBean pb; 
    
        @GET
        @Path("/RegisterDevice")
        public void registerDevice(
            @QueryParam("deviceId") String deviceId){
    
            Device d = new Device(true);
            d.setId = deviceId;
            pb.addDevice(d);
        }
    }
    

    and EJB class:

    @Stateless(mappedName = "PersistenceBean")
    public class PersistenceBean {
    @PersistenceUnit(unitName = "PersistentUnitName")
    EntityManagerFactory emf;
    
    private void persist(Object o, EntityManager entityManager) {
        try {
            entityManager.persist(o);
        } catch (Exception e) {
            logger.severe("Error writing to DB: " + e);
            logger.severe("" + e.fillInStackTrace());
        }
    }
      public void addDevice(Device d) {
        try {
            EntityManager em = emf.createEntityManager(); 
        if (persist(device, em)) {
                logger.info("Device with id : " + device.getId()
                        + " has been added ");
    } else {
                logger.info("Failed to add device with id: " + device.getId());
    } catch (Exception e) {
            logger.severe("PersistenceBean: Could not save device.");
            e.printStackTrace();
    }
    
    }
    

    upadate:

    EAR
      --EarContent
        --META-INF
           --application.xml
    EJB
      --package in ejbModule
        --PersistenceBean
        --Device
      --META-INF
        --ejb-jar.xml
        --MANIFEST.MF
        --persistence.xml
        --beans.xml
    
    Web
      --package in webModule
        --Rest (auto generated class while creating Webservice)
        --RestPush
      --WebContent
        --META-INF
          --MANIFEST.MF
        --WEB-INF
          --web.xml
          --beans.xml
    

    stack trace:

    `10:23:28,629 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/RestWeb].[Resteasy]] Servlet.service() for servlet Resteasy threw exception: org.jboss.resteasy.spi.UnhandledException: java.lang.NullPointerException
    at 
    Caused by: java.lang.NullPointerException
    at package.RestPush.registerDevice(RestPush.java:68) [:]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_27]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [:1.6.0_27]
    
  • user2377971
    user2377971 almost 11 years
    well i tried that before and changing annotation from EJB to Inject changes nothing, still null pointer when calling pb.addDevice(d);
  • Carlo Pellegrini
    Carlo Pellegrini almost 11 years
    Are you sure that your objects are getting injected? Where did you put the CDI beans.xml file?
  • user2377971
    user2377971 almost 11 years
    mayby that is the problem i don't have any beans.xml file
  • Carlo Pellegrini
    Carlo Pellegrini almost 11 years
    Definitely, you need it in WEB-INF fro WAR modules or in META-INF for jar (ejb or lib) modules. See docs.oracle.com/javaee/6/tutorial/doc/gjbnz.html
  • user2377971
    user2377971 almost 11 years
    ok i created beans.xml web module, code: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> </beans> but it didn't help
  • Carlo Pellegrini
    Carlo Pellegrini almost 11 years
    Could you post your EAR structure? Remember that if beans.xml is not in the module/lib jars also, they will not be scanned by CDI.
  • Carlo Pellegrini
    Carlo Pellegrini almost 11 years
    On Web/WebContent move beans.xml from META-INF to WEB-INF (otherwise it's not located). Add beans.xml to EJB/META-INF. Remember to use @Inject.
  • user2377971
    user2377971 almost 11 years
    again thanks for helping, but still NullPointer when trying to access pb.addDevice(); ... Tried with @Inject and few types of Beans annotations eaven with @EJB - excepting miracle
  • Carlo Pellegrini
    Carlo Pellegrini almost 11 years
    Mmmm.. could you post also the exception? (full stacktrace)
  • user2377971
    user2377971 almost 11 years
    i have tried answer of Dependency injection in restful WS and after following it step by step im alse getting nullpointer also
  • user2377971
    user2377971 almost 11 years
    don't know if it's related but when instead of Rest i'm using Servlet - dependency injections works perfect
  • Carlo Pellegrini
    Carlo Pellegrini almost 11 years