I am developing two OSGI bundles with Equinox Eclipse and Hibernate/JPA trying to persist one Entity using Unmanaged JPA.
The first bundle: "Testhibernate" is a bundle that export all the packages from the hibernates jars and has an Activator "org.hibernate.osgi.HibernateBundleActivator" that register an OSGI Service and also use the Equinox tag Eclipse-BuddyPolicy: registered.
The second bundle: "TesthibernateConfigDAO" just have a dependency for the first bundle and also in the Manifest.mf file has the tag Eclipse-RegisterBuddy: Testhibernate to link the persistence.xml file.
In this second blundle when I run both in the OSGI Equinox container, if I use the method:
emf = Persistence.createEntityManagerFactory("PersistenceProcessDataUnit");
then I get the EntityManagerFactory and I get to persist my entity right in database and all is OK.
But I read in the official hibernate website the next:
17.4.3. Obtaining an EntityMangerFactory
hibernate-osgi registers an OSGi service, using the JPA PersistenceProvider interface name, that bootstraps and creates an EntityManagerFactory specific for OSGi environments. It is VITAL that your EMF be obtained through the service, rather than creating it manually. The service handles the OSGi ClassLoader, discovered extension points, scanning, etc. Manually creating an EntityManagerFactory is guaranteed to NOT work during runtime!
For an example on how to discover and use the service, see the unmanaged-jpa QuickStart's HibernateUtil.java.
So I try to get the EntityManagerFactory with this:
Bundle thisBundle = FrameworkUtil.getBundle( HibernateUtil.class );
BundleContext context = thisBundle.getBundleContext();
ServiceReference serviceReference = context.getServiceReference( PersistenceProvider.class.getName() );
PersistenceProvider persistenceProvider = (PersistenceProvider) context.getService( serviceReference );
emf = persistenceProvider.createEntityManagerFactory( "PersistenceProcessDataUnit", null );
I've debuged this and I just get the service and the persistenceProvider object right, but when I execute the last trying to get the EntityManagerFactory then I get the error:
org.osgi.framework.BundleException: Exception in testhibernateconfigdao.HibernateJpaActivator.start() of bundle TesthibernateConfigDAO. at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:734) at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683) at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381) at org.eclipse.osgi.framework.internal.core.AbstractBundle.resume(AbstractBundle.java:390) at org.eclipse.osgi.framework.internal.core.Framework.resumeBundle(Framework.java:1176) at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:559) at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:544) at org.eclipse.osgi.framework.internal.core.StartLevelManager.incFWSL(StartLevelManager.java:457) at org.eclipse.osgi.framework.internal.core.StartLevelManager.doSetStartLevel(StartLevelManager.java:243) at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:438) at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:1) at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340) Caused by: javax.persistence.PersistenceException: Unable to configure EntityManagerFactory at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:387) at org.hibernate.osgi.OsgiPersistenceProvider.createEntityManagerFactory(OsgiPersistenceProvider.java:83) at de.test.HibernateUtil.getEntityManagerFactory(HibernateUtil.java:29) at de.test.HibernateUtil.getEntityManager(HibernateUtil.java:18) at testhibernateconfigdao.HibernateJpaActivator.start(HibernateJpaActivator.java:24) at org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:711) at java.security.AccessController.doPrivileged(Native Method) at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:702) ... 12 more Caused by: java.lang.NullPointerException at org.hibernate.osgi.OsgiScanner.getFilesInJar(OsgiScanner.java:112) at org.hibernate.ejb.Ejb3Configuration.addScannedEntries(Ejb3Configuration.java:506) at org.hibernate.ejb.Ejb3Configuration.addMetadataFromScan(Ejb3Configuration.java:477) at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:363) ... 19 more
And I spend more than 3 days reading oficcial documentation and I dont get it what is the problem.
Your set-up won't work. You can only create the EMF if the persistence.xml with the unit description is accessible from the code you create the entity manager factory in. In this case you create the factory in the bundle that does not contain the persistence.xml. The NPE is probably the result of a missing null check in the hibernate code to BundleWiring.listResources (a bug of course), but this is the mere result of not being able to access the persistence unit description file.
You should create the entity manager factory in the TestHibernate bundle and register the EMF as a service. The DAO bundle can then look-up this service and perform its actions.
By the way: this is also the way in which an OSGi compliant solution would work given the OSGi specifications. I would suggest looking at the examples in the Gemini JPA download and reading the OSGi specifications related to JPA and JNDI (download via the OSGi Alliance site). But maybe you already did this.