users@glassfish.java.net

RE: OSGi Java EE hybrid example split into modules best practices

From: Kirk Rasmussen <kirk.rasmussen_at_texturacorp.com>
Date: Wed, 29 Feb 2012 10:05:06 -0600

See comments below

>On Tuesday 28 February 2012 09:35 PM, Kirk Rasmussen wrote:
>> Sahoo suggested using an interceptor as follows:
>>
>> @AroundInvoke
>> Object setEM(InvocationContext ctx) throws Exception {
>> log("entering setEM()");
>> utx.begin();
>> em = emf.createEntityManager();
>> em.joinTransaction();
>> try {
>> Object result = ctx.proceed();
>> utx.commit();
>> return result;
>> } catch (Exception e) {
>> utx.rollback();
>> throw e;
>> }
>> finally {
>> em.close();
>> log("exiting setEM()");
>> }
>>
>> This a nice work around but its container specific code that I
>> wouldn't need in Aries for example making my code non-portable which
>> makes me sad. IMHO for Enterprise OSGi to take off mainstream issues
>> like this need to be resolved. OSGi applications need to support
>> managed JPA, declarative transactions and security as transparently
>> and as portably as EJB3.
>>
>I don't understand what is container specific here? Interceptor is a
supported technology in EE platform - nothing specific to GlassFish.
>That code will work exactly same way in JBoss, WebLogic and WebSphere.
>Aries required you to write some XML instead of this code - that's the
way I like to see things.

I meant that the code above would be unnecessary on Aries (i.e.
container specific albeit portable). From my understanding on Aries the
EntityManager is managed for me already without the need for the
interceptor, on Glassfish it is not.

Our goal as software developers is to REDUCE the amount of code we write
and maintain. I'm not saying I prefer XML over CDI because I don't but I
also don't like the idea of needing to write extra code to make it work
like Aries does already. It's error prone.

For example the other "fighterfish" samples don't include the call to
"em.joinTransaction()" as the interceptor above which from my
understanding is required ("Enterprise JavaBeans 3.1: 6th Edition", pg
138). IMHO It's too easy to make a mistake (no call to
em.joinTransaction() below).

glassfish-samples/sample/uas/ejbservice2/src/main/java/org/glassfish/fig
hterfish/sample/uas/ejbservice2/UserAuthServiceEJB2.java:

    @Override
    public boolean register(String name, String password) {
        log("Registering (" + name + ", " + password + ")");
        EntityManager em = emf.createEntityManager();
        try {
            UserCredential uc = em.find(UserCredential.class, name);
            if (uc != null) return false;
            uc = new UserCredential();
            uc.setName(name);
            uc.setPassword(password);
            em.persist(uc);
            return true;
        } finally {
            em.close();
        }
    }

If I had to pick between using XML with managed EntityManager vs
relaying on all the other developers in my organization to write the
proper interceptor/API calls I would probably stick with the XML
approach. That's what I meant by fragmenting in the OSGi Enterprise
world. There should be a standard across all containers for obtaining
*managed* EntityManagers.

This situation is analogous to choosing "@Inject @OSGiSErvice" over
using OSGi APIs directly because it is hard to manage services
correctly. @OSGiService is superior because I write less code and it is
reliable every time.

In the ideal world, for OSGi, I should have a choice between injecting
EntityMangerFactory or EntityManager just like I do in a pure JavaEE
world.