users@glassfish.java.net

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

From: Kirk Rasmussen <kirk.rasmussen_at_texturacorp.com>
Date: Thu, 1 Mar 2012 11:02:39 -0600

Hi Ancoron,

Thanks again for the detailed explanation. Your insight into OSGi has
been extremely helpful. As you have surmised I am neither an OSGi expert
nor a Java EE 6 expert. I would say that I am an advanced Spring user
however. I will also endear to use more precise terminology going
forward. I did in fact overload the use of container to mean both "OSGi"
and "Java EE" in different contexts.

Just so you know I have been tasked with evaluating Enterprise grade
OSGi application servers (having no OSGi background) to migrate our web
based applications for its modularity and provisioning capabilities. As
someone new to both OSGi and Enterprise OSGi specifically I found the
learning process very difficult with lots of conflicting advice floating
around the Internet.

It's good to know that EJB interceptors can be reused as easily as a
pointcut declaration in Blueprint and that there are standards based
solutions to address my concerns from a code maintenance perspective.

Glassfish is standing out as one of the premiere solutions just on the
quality of examples, documentation, and the community. Now that I have
revisited Java EE I have to say I am pretty impressed with how far it
has come since 2006 the last time I used it. From what I have seen the
hybrid JavaEE/OSGi approach seems like the best way to go. I've been
using Java based Spring configurations for awhile now so CDI is a more
natural fit.

Picking up from your previous email on DTOs. I hadn't considered
splitting up the entity classes using interfaces before but your email
reminded me of something I read the other day. Seems like a great
solution. One thing I've found about "transparent" ORM is it tends to be
anything but transparent!

> As a test I also took this one step further and introduced good-old
> DTOs implementing the same interfaces for the outside users (so they
> don't even see that I'm using JPA or whatever I use internally to
> manage persistence). This way I make sure that modification of an
> object instance I give to the outer user does not implicitly trigger
> the entity manager and also that I don't have unexpected
> updates/inserts once the outer transaction (if there is any) commits.
>
> Also this provides the user of my persistence with a guaranteed
> reliability, as only I can control the lifecycle of entities, caching,

> lazy-loading, ... , including ensuring the load-modify-save principle
> (I've lately seen quite some applications not caring about the "load"
> part, just creating new entities, set some values and expect the JPA
> implementation to do the right thing - in all cases).
>
>
> This may be a bit overly complex but it solves a lot of problems when
> you don't know how others will use your stuff (or how many layers will

> be there on top of yours, or which transactional characteristics they
> may apply - or not).

From Enterprise OSGi in Action, pg 147:

"There are clear advantages to using interfaces to hide our
entity classes,
however it isn't a perfect solution. It is very easy for the
data access service to
return data objects that have been looked up - either the entity types
will implement
the interface directly, or there can be a wrapper class. Storing or
updating the entity
instances in JPA requires actual instances of the entity class. This
means that the
data access service must be able to create new instances of the entity
classes from
raw data (or other implementations of the interface) that get passed in.
Sometimes
you might get lucky, and find that you can cast the instance you were
passed to an
entity implementation (if, say, it came from a previous lookup), but the
other cases
can involve significant amounts of copying."


Thanks again for your help!


-----Original Message-----
From: Ancoron Luciferis [mailto:ancoron.luciferis_at_googlemail.com]
Sent: Wednesday, February 29, 2012 4:48 PM
To: Kirk Rasmussen
Cc: sanjeeb.sahoo_at_oracle.com; users_at_glassfish.java.net
Subject: Re: OSGi Java EE hybrid example split into modules best
practices

Hi Kirk,

I think we have a bit of a different understanding in the terms we use
here. When talking about "containers", we usually mean "JavaEE
container" or "EJB container", whereas you seem to mean "OSGi
container", which in our wording is the "OSGi framework" or "OSGi
runtime". Could we agree on this? It should make further arguments a bit
simpler to understand.

However, about your concerns:

When I get it right then what you want is the JPA plug'n'play magic to
happen in pure OSGi, rather than the JavaEE container. The main problem
here is, that the OSGi enterprise specs just hit their first official
release with the 4.2 specs. With every specification or "standard" you
will concentrate on a most reasonable subset of functionality and wait
for the feedback before going any further. In some areas even initial
specifications tend to get too complex (like e.g. the D-OSGi stuff and
the RemoteServiceAdmin infrastructure).

Also, "OSGi enterprise" does not strictly depend on "JavaEE" for being
implemented. This puts in some additional constraints to be aware of.
E.g. in a JavaEE environment you usually use JTA managed transactions
and also benefit from managed JPA EntityManagers which fit together
quite nicely because the EntityManagers have a more-or-less pre-defined
lifecycle here, from creation to destroy. In a non-JavaEE environment
you usually do transaction demarcation and all that stuff yourself or
using some other framework, e.g. Spring. For the pure OSGi layer, Apache
Aries has been built exactly for that purpose by reusing Spring
look-a-like configuration files. Hence, you also have to control the
lifecycle of the EntityManager yourself, as the framework does not know
before-hand what you're going to do.

I use Aries as well directly inside GlassFish and configured it to use
the GlassFish JTA manager to get distributed transactions between my own
services (which most commonly use JPA) and the ones from third-party
services that may use any other technology (e.g. one uses MyBatis
configured with a GlassFish managed DataSource).

So basically you don't have to choose once and for all between one
approach or the other. But you should first know where your things might
be running, or which kind of runtime environments you want to support.
The result of this defines the constraints and may render some
approaches as being inappropriate or simply impossible.

So, if you want to be runtime-agnostic you really should stick to the
standard that there is and Apache Aries is one of your best options. If
you can assume GlassFish, then you're free to use at least
JavaEE-specific stuff. Also you have to make some tests which approach
is more reliable or faster than the other. Also (hot-)deployment is a
clear test case for anything within the OSGi space.

See further comments inline...

On 02/29/2012 05:05 PM, Kirk Rasmussen wrote:
>
> 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.

Yes, but you still have to write and maintain that XML which is almost
completely detached from any build time validation or static code
analysis. As many others, I prefer code over configuration, which I can
debug much better, which has a much clearer visibility to other
developers, keeps stacktraces shorter and hence, provides better
maintainability. Also if I face a problem or a strange runtime behavior
- e.g. some race condition - I already have a place to workaround it.
But that's only my point of view.

>
> 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.

Agree, so why don't you just use Apache Aries then?

>
> 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/f
> ig
> 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.

There just can't be a standard across all containers for this because
JavaEE container environments differ a lot from non-JavaEE ones. The
JPA/TX stuff from the Aries project tries to abstract from that fact and
does quite a decent job here but in the end it does not matter if you
write code or XML - you always have to configure the "managed" part
somehow.

Furthermore you seriously don't have all your other developers to write
the interceptor stuff. You just write it once and then re-use it. E.g.
you could provide multiple interceptor implementations handling
different needs. I could think of one interceptor that enforces nested
transactions and one that just sets the transactional boundaries in case
there is no transaction and in the other case just reuses the existing
one.

Package that interceptor inside a common bundle that is shared across
your implementations and you're all set up. In the Aries case you would
have to configure each and every service with the additional XML stuff.

E.g. for EJB implementations of services I usually use the classic
JavaEE @javax.interceptor.Interceptors annotation. That annotation is
packaged inside a shared bundle and hence, ready for use by everyone. No
code writing is required for a new service implementation on that part.
This is the principle of "write ones - use everywhere", so I have a
single class to maintain, nothing else.

With CDI this would basically be the same, whereas you would provide
your own interceptor annotation in addition for this. An example
(although without the OSGi part) is here:

https://blogs.oracle.com/arungupta/entry/totd_151_transactional_intercep
tors_using

On the other side, to support your other developers using the OSGi
blueprints approach you then have to check their projects in case of
problems instead of limiting your scope of visibility and responsibility
to the least possible.

So, in the end this proves your point of writing less code when using
Aries completely wrong because XML is some sort of code as well.

Sorry. ;)

>
> 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.
>

Well, then you should probably raise your voice as well on the OSGi
developers list to get some more feedback on this topic.

I really encourage you to do that because I would like to see an
official solution to this as well. But I still think there is no really
generic way to do it as will always have something that needs to be
configured and hence, maintained on your side.

Cheers,

        Ancoron