JAX-RS 2.0 integration with EJB and CDI
Java™ API for RESTful Web Services (JAX-RS) 2.0 integrates with Enterprise JavaBeans (EJB) and Contexts and Dependency Injection (CDI) in WebSphere® Application Server 傳統版 V9.
For JAX-RS 2.0 to work with enterprise beans, you need to use @Path to annotate the class of a bean and convert it to a root resource class.
By integrating with EJB, you can annotate the EJB beans to show them as REST endpoints. You can also use the Java Transaction API (JTA) and security functions of EJB. JAX-RS 2.0 in WebSphere Application Server 傳統版 supports the use of stateless and singleton session beans as root resource classes, providers, and application subclasses.
By integrating with CDI, you can annotate CDI beans or Managed beans as REST endpoints and use CDI injection for web services. JAX-RS 2.0 in WebSphere Application Server 傳統版 supports CDI-style beans as root resource classes, providers, and application subclasses. Providers and application subclasses must be singletons or use the application scope. CDI specification makes it easier to integrate Java EE components of different types. It provides a common mechanism to inject components, such as EJB components or Managed beans, into other components, such as Java Server Pages (JSPs) or other EJBs.
- For a stateless session bean, use the @Stateless annotation as is shown in the
following
example:
@Stateless @Path("stateless-bean") public class StatelessResource {...}
- For a singleton bean, use the @Singleton annotation as is shown in the
following
example:
@Singleton @Path("singleton-bean") public class SingletonResource {...}
@ApplicationScoped
@Path("/ApplicationScopedResource")
public class ApplicationScopedResource {
private @Inject
SimpleBean injected;
...
}
Restrictions on JAX-RS 2.0 with EJB and CDI
See the following items for the restrictions of JAX-RS 2.0 in WebSphere Application Server 傳統版:
- If you use EJB as JAX-RS resource, provider or application, you cannot use the
@Context injection on constructor of the EJB bean. Note: The reason for this case is that the EJB with default constructor can be only used for JAX-RS based on EJB and JAX-RS specification.
- For an Application class, if it implements no interface or it has @Localbean annotation, it is seen as EJB. But if it implements local or POJO interfaces, it is not seen as EJB.
- For a Provider, here lists the conditions that a class might be or might not be seen as a valid
EJB provider:
- If a class implements POJO provider interfaces only without the @Local annotation, it is seen as a valid EJB provider.
- If a class has the @LocalBean annotation and it implements the POJO provider interface, it is seen as a valid EJB provider.
- If a class has the local interface with the @Local annotation, the local interface is a provider interface. If this class implements the provider interface, it is a valid EJB provider.
- If a class has a local interface with @Local annotation, and if the local interface is not a provider interface, it is not a valid provider. The reason for this case is that EJB container can generate EJB stub for the local interface only rather than the POJO provider interface.
- If a class has the @Local annotation, but the annotation does not implement the provider interface that it refers to, it is not a valid provider. Based on the JAX-RS 2.0 specification, a provider is a class that implements one or more JAX-RS interfaces that are introduced in this specification and that might be annotated with @Provider for automatic discovery.
- For a Resource, here lists the conditions that the methods in a class are or are not available
as JAX-RS resources:
- If EJB-based resource does not implement any interface, all of the methods that are declared in this class are available as JAX-RS resources.
- If EJB-based resource implements one interface (local or POJO), all the methods that are declared in this interface are available as JAX-RS resources.
- If EJB-based resource implements multiple interface,
- If all the interfaces are POJO interfaces without the @Local annotation, all the methods that are declared in interface are available as JAX-RS resources.
- If all the interfaces are local interfaces with the @Local annotation, all the methods that are declared in the interface are available as JAX-RS resources.
- If some of the interfaces are local interfaces with the @Local annotation while
others are not local interfaces, only the methods declared in the local interfaces are available as
JAX-RS resources. Note: The reason for this case is that the EJB container can generate EJB stub for local interfaces only in this scenario.
- If the EJB-based resource has the @LocalBean annotation, all the methods that are declared in class are available as JAX-RS resource.
- If EJB-based resource implements an interface, JAX-RS resource method must be declared in the interface. If the interface is a provider that can't be modified, you must create a new interface for the resource class to add the resource method. Otherwise, it is not seen as EJB resource.
- If a resource class with the @Path annotation implements JAX-RS provider interface or it declares with the @Provider annotation, this class works as both a resource and a provider. In this case, by default, the JAX-RS 2.0 engine uses only one instance of this class that is shared by the resource and the provider, and the lifecycle of the instance is singleton.
- If a class is registered in both the getClasses and getSingletons methods of the application class, by default, the JAX-RS 2.0 engine uses the instance from the getSingletons method and ignore the registration in the getClasses method.
- If a RESTful resource is also a CDI managed bean and its scope is javax.enterprise.context.Dependent, the PreDestroy method cannot be called because of the CDI restriction.
JAX-RS 2.0 bean and EJB bean lifecycle
Application | JAX-RS 2.0 | EJB | Result |
---|---|---|---|
Resource | perRequest | Stateless | Stateless |
perRequest | Singleton | Singleton | |
Singleton | Stateless | Stateless | |
Singleton | Singleton | Singleton | |
Provider | Singleton | Stateless | Stateless |
Singleton | Singleton | Singleton |
JAX-RS 2.0 scope and CDI scope lifecycle
Application | JAX-RS 2.0 Scope | CDI Scope annotation | Result |
---|---|---|---|
Resource | perRequest | @ApplicationScoped | Singleton |
perRequest | @RequestScoped | perRequest | |
perRequest | @Dependent | perRequest | |
perRequest | @SessionScoped | Session | |
perRequest | perRequest | ||
Singleton | @ApplicationScoped | Singleton | |
Singleton | @RequestScoped | perRequest | |
Singleton | @Dependent | Singleton | |
Singleton | @SessionScoped | Session | |
Singleton | Singleton | ||
Provider | Singleton | @ApplicationScoped | Singleton |
Singleton | @RequestScoped | Singleton | |
Singleton | @Dependent | Singleton | |
Singleton | @SessionScoped | Singleton | |
Singleton | Singleton |
JAX-RS 2.0 scope and CDI scope lifecycle conflict messages
The following warning messages are displayed when the scope lifecycle of JAX-RS 2.0 and CDI conflicts. They are warning messages and no actions are required.
This message is displayed if the JAXRS-2.0 resource scope does not match the CDI scope and the resource instance exists in CDI, so WebSphere Application Server 傳統版 gets the resource instance from CDI. Instance does not include CDI injection if it is from JAXRS.CWWKW1001W: The scope {1} of JAXRS-2.0 Resource {0} does not match the CDI scope {2}. WebSphere Application Server traditional gets resource instance from {3}.
This message is displayed because provider instance is Singleton only. WebSphere Application Server 傳統版 gets provider instance from CDI if the CDI scope of provider is Dependent or ApplicationScoped. Instance does not include CDI injection if it is from JAXRS.CWWKW1002W: The CDI scope of JAXRS-2.0 Provider {0} is {1}. WebSphere Application Server traditional gets the provider instance from {2}.