I'm trying to inject a Stateless EJB into my JAX-RS webservice via annotations. Unfortunately the EJB is just null
and I get a NullPointerException
when I try to use it.
@Path("book") public class BookResource { @EJB private BookEJB bookEJB; public BookResource() { } @GET @Produces("application/xml") @Path("/{bookId}") public Book getBookById(@PathParam("bookId") Integer id) { return bookEJB.findById(id); } }
What am I doing wrong?
Here is some information about my machine:
Can you guys show some working example?
Now for building Restful web service from an EJB class, all that we need to do is to package the web service in a Web application (servlet 3.0/3.1) and create an application class that loads the EJB class as a Rest Root class and annotating the EJB class with @Path annotation.
WebNMS SNMP for EJB has been designed to support EJB applications, and conform to the EJB standards. The EJB standard restricts the Enterprise Java Bean from performing certain functions, such as socket access.
I am not sure this is supposed to work. So either:
Option 1: Use the injection provider SPI
Implement a provider that will do the lookup and inject the EJB. See:
Example for com.sun.jersey:jersey-server:1.17 :
import com.sun.jersey.core.spi.component.ComponentContext; import com.sun.jersey.core.spi.component.ComponentScope; import com.sun.jersey.spi.inject.Injectable; import com.sun.jersey.spi.inject.InjectableProvider; import javax.ejb.EJB; import javax.naming.Context; import javax.naming.InitialContext; import javax.ws.rs.ext.Provider; import java.lang.reflect.Type; /** * JAX-RS EJB Injection provider. */ @Provider public class EJBProvider implements InjectableProvider<EJB, Type> { public ComponentScope getScope() { return ComponentScope.Singleton; } public Injectable getInjectable(ComponentContext cc, EJB ejb, Type t) { if (!(t instanceof Class)) return null; try { Class c = (Class)t; Context ic = new InitialContext(); final Object o = ic.lookup(c.getName()); return new Injectable<Object>() { public Object getValue() { return o; } }; } catch (Exception e) { e.printStackTrace(); return null; } } }
Option 2: Make the BookResource an EJB
@Stateless @Path("book") public class BookResource { @EJB private BookEJB bookEJB; //... }
See:
Option 3: Use CDI
@Path("book") @RequestScoped public class BookResource { @Inject private BookEJB bookEJB; //... }
See:
This thread is rather old, nevertheless i fought the same problem just yesterday. Here is my solution:
Just make the BookResource a managed bean through @javax.annotation.ManagedBean at class level.
For this to work you need to enable CDI with a beans.xml:
<?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>
This file needs to be in WEB-INF if the BookResource is part of a war file. If the BookResource is packaged with the ejbs put it into META-INF.
If you want to use @EJB you're done. If you want to inject the EJB through @Inject than a beans.xml must be put into the ejbs jar file into META-INF as well.
What you're doing: You're just telling the container that the resource should be container managed. Therefor it supports injection as well as lifecycle events. So you have your business facade without promoting it to an EJB.
You don't need to extend javax.ws.rs.core.Application for this to work. BookResource is as a root resource automatically request scoped.
Tested with Glassfish 3.1.2 and a maven project.
Happy coding.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With