I am trying to inject and EJB 3.1 in one of my RESTful services. I've followed the post: Inject an EJB into JAX-RS (RESTful service) and tried all options except building an injection provider. The current solution that I am trying uses a combination of @RequestScoped
and @Inject
, but my injected bean variable is still null
. I have a beans.xml
in the /WEB-INF
folder.
How can I inject an EJB into my REST service class?
UserService
@Local
@Path("user/v1")
@Produces(MediaType.APPLICATION_JSON)
public class UserServiceV1 implements SystemLogger {
@Inject
private ApplicationBean appBean;
@GET
@Path("pingbean")
@Produces(MediaType.APPLICATION_JSON)
public Response pingAppBean() {
if(appBean == null) {
return Response.status(Response.Status.UNAUTHORIZED).entity("{\"faild\": \"App bean is null\"}").build();
}
String message = appBean.getHello();
return Response.status(Response.Status.OK)
.entity(message)
.build();
}
}
ApplicationBean
The SystemHandler
resides in jar module and is a standard class with business logic.
@Stateless
@Local
public class ApplicationBean implements ApplicationBeanLocal {
@Override
public String getHello() {
return "Hello from ApplicationBean";
};
}
JAX-RS configuration
@ApplicationPath("service")
public class ApplicationService extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new HashSet<>();
resources.add(UserServiceV1.class);
resources.add(ApplicationBean.class);
resources.add(CorsFilterProvider.class);
return resources;
}
}
Exception
14:07:01,230 ERROR [io.undertow.request] UT005023: Exception handling request to /MyApp/service/user/v1/login: org.jboss.resteasy.spi.UnhandledException: java.lang.NullPointerException
at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:76) [resteasy-jaxrs-3.0.14.Final.jar:3.0.14.Final]
at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:212) [resteasy-jaxrs-3.0.14.Final.jar:3.0.14.Final]
Resteasy /JAX-RS I've added a CDI implementation for resteasy according to the documentation
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.14.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-cdi</artifactId>
<version>3.0.14.Final</version>
<scope>provided</scope>
</dependency>
EDIT: changed code details in the question and title
EJB 3.1 implies a Java EE 6 container implementation. Java EE 6 implies JAX-RS 1.1.
JAX-RS 1.1 is only required to support @EJB injection of enterprise java beans.
JAX-RS 2.0 as provided in a Java EE 7 implementation supports @Inject for EJBs.
As Steve C answered, the proper way to inject an EJB in JAX-RS 1.1 is with the javax.ejb.EJB annotation. The REST service must also be an EJB for this to work. As such, you have to use the javax.ejb.Stateless annotation instead of javax.enterprise.context.RequestScoped.
The end result is as follows:
EDIT
Your updated code doesn't deploy. Either have
ApplicationBean
implementApplicationBeanLocal
and inject the interface, or don't implement it and inject the class directly. With that corrected, I managed to run your example just fine.Also, in
ApplicationService
, you don't need to addApplicationBean.class
. You only register there REST root resources and feature providers.@Local
is also unnecessary in theUserServiceV1
class, it's not an EJB.Furthermore, it's
beans.xml
, notbean.xml
(but this file is not necessary anymore from CDI 1.1 on).See my testcode below:
pom.xml
dependencies for the jar module:ApplicationBeanLocal.java
:ApplicationBean.java
:pom.xml
dependencies for the JAX-RS application:TestApplication.java
:UserServiceV1.java