views:

1336

answers:

5
+3  Q: 

OSGi + Hibernate

Instead of having database actions scattered in four (osgi) bundles, all doing there slightly different things. I want to create a (simple) OSGi bundle that is responsible for all persistance issues. I feel that this is not as simple as it sounds because of the "unique classloader per bundle" thing. So what I really would appreciate is if someone knows the solution(s) to this kind of problem.

+2  A: 

There are two way I can think of to solve the classloading-issue.

  • Are you tied to a specific OSGi-Framework, or do you want to stay as compatible as possible? Or can you use equinox for your implementation? In Equinox you have a mechanism called Buddy Classloading. This addition allows you to increase the visibility of certain classes between different OSGi-Bundles. If you are interested in this topic, I would like to direct you to these two articles: Understanding how Eclipse plug-ins work with OSGi, Eclipse - a tale of two VMs (and many classloaders).
  • If you prefere to stay OSGi-implementation independent, then you might considre extracting your calsses, that you wish to persist, into a separate bundle on which both the Hibernate-Bundle and your other bundles depend. That way, they all have access to the class definition of the persisted classes.
Stefan Schmidt
+1  A: 

Just found an interesting method in the Bundle class/api.

public java.lang.Class loadClass(java.lang.String name) throws java.lang.ClassNotFoundException

This must solve some class loader issues?

A: 

(If you are using Hibernate Annotations)

Save all the Entities class loaders when the Hibernate bundle is informed about an annotated class.

Then do something like this before building your SessionFactory.

ClassLoad cl = Thread.currentThread().getContextClassLoader();
try {
 Thread.currentThread().setContextClassLoader(yourClassLoader);
 factory = cfg.buildSessionFactory(); 
}finally {
 Thread.currentThread().setContextClassLoader(cl);  // restore the original class loader
}
Schildmeijer
A: 

I'm going to recommend to stay away from buddy class loading as it's specific to Eclipse's Equinox implementation and, in my opinion, people get it to work but they don't understand why and everyone ends up as a buddy of everyone else. This stops you gaining a proper understanding of how OSGi classloading works and the patterns you need to use (composite class loaders, context class loading, OSGi services, ...) to work with it.

If your persistence bundle knows ahead-of-time what types it needs to persist, then the bundle can import all required packages (Require-Bundle is evil) that contain your domain classes.

Managing the context class loader (as in Roger's reply) can help with Hibernate, though I'd suggest using something like Spring dm to hide that behind an OSGi service.

A: 

This is the most elegant solution:

http://notehive.com/wp/2008/07/23/osgi-hibernate-spring-dm-sample/

James Kingsbery