> For OSGi containers, in addition to having the JDO jar compliant,
> some additional infrastructure is needed, for example the
> implementation jar should also contain a service definition for JDO.
> AI Erik write up proposal for the group.
>

Proposal for J2SE Service Discovery and OSGi Service Discovery for JDO

Provide transparent and less development time (in terms of pmf properties)
dependencies to JDO vendors, enabling runtime discovery.

J2SE Service Discovery
-------------------------------
The goal is provide more transparent replacement of implementation for
operations/deployment or easier bootstrap mechanism for creating JDO instances.
For awareness this proposal uses a similar mechanism to JPA.

An Use Case is an application deployed to production environment which uses JDO
implementation A and is not performing well. It was identified the problem was
within the JDO implementation A, and to fix the issue it was decided to replace
the implementation with a different vendor. The procedure consists in replacing
the JDO vendor jar in the classpath and update the PMF properties pointing to
the new vendor PMF class.
With a service discovery this procedure would be reduced down to replacing only
the JDO vendor jar.

To implement such thing we can use the standard jar specification.

How does it work for the jdo user :

As before, by using the JDOHelper.getPMF(properties). However there is no need
to set the property javax.jdo.PersistenceManagerFactoryClass if there is only
one JDO vendor jar in the classpath.

How does it work for the implementation :

In the JDO jar file, add the file
/META-INF/services/javax.jdo.PersistenceManagerFactory, and inside the
file set the fully qualified class name for the PMF implementation.

The JDOHelper.getPMF(properties) will do the service discovery, by using the
standard jar spec.

This service discovery is very likely to be used in J2SE environments.

See:

jar spec
jpa spec (for an example of this service)

OSGi Service Discovery for JDO
-------------------------------

The idea here is make better integration between JDO and OSGi, and the ultimate
goal is to provide an OSGi service that can instantiates JDO PMFs.

In OSGi containers, the service discovery uses similar concepts, but has
different implementations, plut the way classloaders are handled is much more
complex.

>From points 1 to 6 I expose the problems that occurs with OSGi development and
JDO.

1)
An OSGi application is usually split into several jars, something like:

mycomponent1.jar (OSGi bundle)
mycomponent2.jar (OSGi bundle)
mycomponent3.jar (OSGi bundle)

2)
Each OSGi bundle is loaded by a different classloader, java runtime classloader
is parent for the bundle classlaoders.
Each component can include libraries inside, for instance JDO. So:

mycomponent1.jar (OSGi bundle)
  - jdo.jar
  - Person.class (PersistenceCapable)
  - Company.class (PersistenceCapable)
mycomponent2.jar (OSGi bundle)
mycomponent3.jar (OSGi bundle)

3)
For the moment only component1 uses the Persistent classes, but if mycomponent3
needs to read Company instances, you will
also need the Persistent classes + jdo.jar in the classpath. Then you decide to
duplicate the classes to both OSGi bundles

mycomponent1.jar (OSGi bundle)
  - jdo.jar
  - Person.class (PersistenceCapable)
  - Company.class (PersistenceCapable)
mycomponent2.jar (OSGi bundle)
mycomponent3.jar (OSGi bundle)
  - jdo.jar
  - Person.class (PersistenceCapable)
  - Company.class (PersistenceCapable)

4)
Easy?? No, actually it will fail with ClassCastException at runtime, since
Person of component1 is not castable
to Person of component3. Solution:

mycomponent1.jar (OSGi bundle) - depends on mydomainclasses.jar and jdo.jar OSGi
bundles
mycomponent2.jar (OSGi bundle)
mycomponent3.jar (OSGi bundle) - depends on mydomainclasses.jar and jdo.jar OSGi
bundles
jdo.jar (OSGi bundle)
  - jdo.jar
mydomainclasses.jar (OSGi bundle) - depends on jdo.jar
  - Person.class (PersistenceCapable)
  - Company.class (PersistenceCapable)

So this fixes the issue of ClassCastException.

5)
Problem: Where to put the jdo vendor implementation?
Actually it can be put anywhere, unless you also want to share instances of the
JDO vendor classes at runtime between
OSGi bundles. The best choice is this:

mycomponent1.jar (OSGi bundle) - depends on mydomainclasses.jar, jdo.jar and
VENDOR_X.jar OSGi bundles
mycomponent2.jar (OSGi bundle)
mycomponent3.jar (OSGi bundle) - depends on mydomainclasses.jar, jdo.jar and
VENDOR_X.jar OSGi bundles
jdo.jar (OSGi bundle)
  - jdo.jar
mydomainclasses.jar (OSGi bundle) - depends on jdo.jar
  - Person.class (PersistenceCapable)
  - Company.class (PersistenceCapable)
VENDOR_X.jar (OSGi bundle)

6)
Problem: How to remove the dependency to the JDO vendor jar at build time?
Have an OSGi Service that discovers the implementation in the OSGi container and
permits to create a PMF instance.

mycomponent1.jar (OSGi bundle) - depends on mydomainclasses.jar and jdo.jar OSGi
bundles
mycomponent2.jar (OSGi bundle)
mycomponent3.jar (OSGi bundle) - depends on mydomainclasses.jar and jdo.jar OSGi
bundles
jdo.jar (OSGi bundle) - provides Service JDOPMF
  - jdo.jar
mydomainclasses.jar (OSGi bundle) - depends on jdo.jar
  - Person.class (PersistenceCapable)
  - Company.class (PersistenceCapable)
VENDOR_X.jar (OSGi bundle) - implements Service JDOPMF

See

osgi spec for more details on osgi services (osgi.org)

Finally, how is this service implemented in OSGi?

A sample will come soon. As soon as I have time to pack something, but I must
say the implementation is very stupid.

Reply via email to