users@jersey.java.net

Re: [Jersey] Exposing EJB 3 Beans through JAX-RS

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 09 Sep 2008 11:19:48 +0200

On Sep 8, 2008, at 7:46 PM, Reza Rahman wrote:

> Paul,
>
> * Essentially they expose out IoC functionality that would is likely
> to be hidden inside more traditional EJB EE 5 implementations.
> - I'm still not sure how this directly effects Jersey/the JAX-RS
> spec though, other than perhaps the perceived market demand, which
> changes by day and is something that better EJB 3.1/JAX-RS
> integration could drive :-).
>

It is not just the spec but how developers can better build Web
applications. The ability to easily wire components together using a
unified model can be a very flexible way to build Web applications. It
is quite clear from the success of Spring and Seam that this is not
just a fad and it does not change every day. Thus i think it important
for EE 6 to include, improve and standardize such capabilities that
have proved itself out in the market.


> * It was not obvious, and is perhaps not possible in some cases, to
> do that for EJB in EE 5.
> - That's what I'm trying to get at...what cases in particular?
>

The POJO development model (which as i understand could be done with
EJB 3.1). Per-request life-cycle. Injection onto fields.


> * It most likely would. But what i would really like to see is IoC
> and EJB POJOs in EE 6.
> - Would you care to expand on this? You can the ability to inject
> non-managed components to EJBs? What do you mean by EJB POJOs? You
> need a handle to the actual bean instance? Why so? Or are you just
> talking about Session Beans without interfaces (already slated for
> EJB 3.1).
>

Yes session beans without interfaces. If EJBs can be just POJOs
without the need to require an interface then i think it becomes a lot
simpler if one is not interested in exposing a session bean out using
RMI/IIOP. If the POJO instance can be obtained via JNDI then that
would help a lot.


> * Take a look at the autowire Spring example in Jersey [1].
> - Nice, but still not as powerful as placing a few annotations on an
> EJB 3 bean and have all the infrastructure concerns be handled
> behind the scenes :-). Kindly take a look at the JBoss RESTEasy
> implementation examples...
>

I think you can do similar things in Spring (e.g. transacted methods),
but i take your point it might be more concise in EJB, although i do
not know all the auto-wire aspects of Spring so the degree of
conciseness may well be minimal e.g. to declare this method is
transacted. In general some of the high-level concepts are very similar.

I believe i have managed to get support for stateless session beans
working effectively in Jersey and make it work without requiring
registration of JNDI resources, but i do not know if what i have
implemented is portable or not. I think it is rather nice in terms of
integration for those that wish to use the stateless session bean
programming model and get all the goodness that comes with it.


> * Stateless session beans are equivalent to singletons.
> - I am guessing you are referring to Spring's singleton
> implementation?

Yes, but also in general as one instance per application. In JAX-RS we
have not specified life-cycles beyond the per-request. We want to be
clearer about that for EE 6 integration. Jersey implements singletons
directly or can defer to spring or another IoC framework, but also now
can defer to stateless session beans, thanks to your prompting and
encouragement :-)


> That's definitely true. Does a single request mandate multiple calls
> to a single bean instance that maintains state? That's the only case
> where stateless session beans would not suffice? Or are you
> referring to the need to inject resources from the JAX-RS end before
> a request can be serviced? Again, I'm trying to understand the
> underlying concerns here a little better?
>

Here is an example of a per-request resource:

@Path("/perrequest")
public class PerRequestResource {
    // A per request query parameter can be injected
   @QueryParam("a") private int a;

   HttpHeaders headers;

   // A public constructor can be used
   public PerRequestResource(@Context HttpHeaders h, @Context UriInfo
ui) {
     this.headers = h;
     if (resource does not exist)
        throw new WebApplicationException(404);
   }

   @GET
   public String get(@QueryParam("b") BigDecimal d) {
     return a + d.toString();
   }
}

Here is an example of a Jersey supported singleton:

@Path("/singleton")
@Singleton
public class PerRequestResource {
   // Injection can be performed, but not for @*Param
   @Context UriInfo ui;

   HttpHeaders headers;

   // A public constructor can be used, but not with @*Param
   public PerRequestResource(@Context HttpHeaders h) {
     this.headers = h;
     // create some other shared state
   }

   @GET
   public String get(@QueryParam("a") int a, @QueryParam("b")
BigDecimal d) {
     if (resource does not exist)
        throw new WebApplicationException(404);
     return headers + ui + a + d.toString();
   }
}

Here is an example of how one could use session bean remote interface
as currently supported in Jersey:

@Path("/ssb")
@Remote
public interface StatelessSessionBean {
    @GET
    public String get(@Context UriInfo ui, @Context HttpHeaders h,
       @QueryParam("a") int a, @QueryParam("b") BigDecimal d);
}

one could also use setter methods:

@Path("/ssb")
@Remote
public interface StatelessSessionBean {
    @Context
    public void setUriInfo(UriInfo ui);

    @Context
    public void setHeaders(HttpHeaders ui);

    @GET
    public String get(@QueryParam("a") int a, @QueryParam("b")
BigDecimal d);
}


> * Yes. Although from a REST perspective this is not recommended as
> it breaks stateless constraint.
> - So how do Spring session scope beans fit in? Don't they have the
> same problem?
>

Yes. It is not a recommended practice whether utilizing Jersey, Spring
or EJB-based session support. I implemented in Jersey for pragmatic
reasons and from developer feedback.


> * Yes, if such fields are annotated.
> - Could you kindly give me an example so I can chat about it in the
> EJB 3.1 EG?
>

Did the above examples help?


> For illumination, could you tell me what is specifically barring the
> same kind of integration that JAX-WS 2.0 has with EJB 3? Again, it's
> particularly puzzling to me in view of the JBoss RESTEasy
> implementation that does support seamless integration with EJB 3?
> What are the challenges with Jersey that they did not have?
>

I implemented limited support yesterday :-) i think that is about as
far as i can go without diving into the specifics of an EJB
implementation. The main challenges as we have already discussed are
to support the per-request life-cycle and injection onto fields of
singletons.


> I'll be honest, I'd hate to see a potentially good technology like
> JAX-RS be out of the reach of developers that would rather use a
> plain EJB stack for reasons that are relatively easily solvable. I
> definitely do hope for much better coordination between specs in
> Java EE than that, particularly in the GlassFish project!
>

I hope by the fact that i have spent time implementing/emailing
counters any suggestion that i am not interested in improving such
things.

Paul.