Inject an EJB into JAX-RS (RESTful service) Inject an EJB into JAX-RS (RESTful service) java java

Inject an EJB into JAX-RS (RESTful service)


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. */@Providerpublic 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")@RequestScopedpublic 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.


You shall be able to do injection in JAX-RS resource without making it EJB or CDI component. But you have to remember that your JAX-RS resource must not be singleton.

So, you setup your application with this code. This makes BookResource class per-request JAX-RS resource.

@javax.ws.rs.ApplicationPath("application")public class InjectionApplication extends javax.ws.rs.core.Application {  private Set<Object> singletons = new HashSet<Object>();  private Set<Class<?>> classes = new HashSet<Class<?>>();  public InjectionApplication() {    // no instance is created, just class is listed    classes.add(BookResource.class);  }  @Override  public Set<Class<?>> getClasses() {    return classes;  }  @Override  public Set<Object> getSingletons() {    return singletons;  }}

With this setup, you are letting JAX-RS to instantiate BookResource for you on per-request basis and also inject all the required dependencies. If you make BookResource class singleton JAX-RS resource, this is, you put in getSingletons

public Set<Object> getSingletons() {  singletons.add(new BookResource());  return singletons;}

then, you created instance which is not managed by JAX-RS runtime and nobody in container cares to inject anything.