JAX-RS Resource as Session Bean or CDI Managed Bean?

Asked

Viewed 455 times

7

Today I ran into an interesting problem trying to inject an EJB into a JAX-RS feature (in Glassfish 4.1, running the pre-installed version of Jersey).

@Stateless
public class MeuEJB implements MinhaInterface {
   // código
}

@Path("caminho")
public class MeuRecurso {
    @Inject
    private MinhaInterface minhaInterface;   
   // código
}

When trying to access the resource received a 500 Internal Server Error saying that there were no valid candidates for injection of MinhaInterface.


Trying to get into it discovered that since version 2.0 of Jersey it includes an Ioc library called HK2. This container apparently knows nothing a priori about the CDI or EJB scopes.

An obvious alternative is to do the jndi lookup manually. In addition there are solutions with InjectionManager and with SPI.

That said, the very Java EE 7 tutorial gives two recipes to integrate JAX-RS with EJB.

  1. Turn the resource into an EJB:

    @Path("caminho")
    @Stateless
    public class MeuRecurso {
        @EJB
        private MinhaInterface minhaInterface;   
        // código
    }
    
  2. Turn the resource into a CDI bean:

    @Path("caminho")
    @RequestScoped
    public class MeuRecurso {
        @Inject
        private MinhaInterface minhaInterface;   
        // código
    }
    

Both alternatives work correctly. What I’d like to know from an architectural (and practical) point of view is: What are the implications of turning my JAX-RS resource into a Stateless Session Bean or in a CDI Managed Bean? Best practices have already been defined on this front?

2 answers

6


There are some differences between using a JAX-RS endpoint as a CDI bean / Stateless bean or not using either. From a practical point of view, I don’t see much differentiation between which to use, CDI or EJB, other than those already known differences between them.

Below are two practical points that are the most important:

  1. Transaction Spread: Both with the @Transactionattribute (EJB) or @Transactional(CDI) give the possibility to encapsulate the transaction and define whether it will be propagated to "levels / layers / dependency or whatever" smaller, for example you can define that a single request will be fully involved in a transactional unit.
  2. JAAS security features (EJB only) right on your resources, with @Rolesallowed you can define your basic security scheme without any additional work.
  3. Addiction injection: Here it is the same thing for both of you, as you yourself have seen.
  4. Direct access to Entitymanager (and any other resource, JMS, JCA etc): In cases of simple CRUD, I don’t see why to bloat the code and use a 3-layer Pattern(etc) for this, at this practical point, use a em.merge(...) directly in its class JAX-RS, greatly simplifies life.

In short, the issue of having a JAX-RS with EJB or JAX-RS with CDI changes nothing unless you have to use some of the specific features of these two Apis. In the case of lifecycle instances between using or not, I see that it’s pretty much the same since jaxrs endpoints are already managed by the container.

Go from CDI until you need to use some EJB-specific Eature. Although these days there is no big difference in performance.(REF).

1

There is no such need, the JAX-RS specification already defines that the life cycle of a Resource is by request. It makes no sense to brand it as @Stateless, by default it has not been.

I don’t think they have defined a good practice for this yet. I use CDI with @Inject, it is already enough for my needs within a Source.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.