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