>However, if you entities, etc. spread across multiple Bundles, will the PersistenceUnitInfo#getClassLoader() be able to load from all of them? How does that ClassLoader know what to include? How specific is that to the given OSGi container implementation? Will that affect Hibernate's need to scan for orm.xml, legacy mapping XML files, entities, etc. not explicitly identified in the persistence unit?

I'm going to cover with the container perspective (which is much easier for Hibernate to support). The JPA runtime (e.g. Aries) is responsible for finding the the persistence bundle (defined as the one containing persistence.xml), and creating a classloader that can load the persistence.xml, all the entities, and any mapping files. 

In practice the ClassLoader used is the ClassLoader for the persistence bundle. Any entities that are used in the persistence bundle must be imported into it, or else they don't exist (as far as the persistence bundle is concerned). The ClassLoader "knows" what to include because of the Import-Package/Require-Bundle headers in the persistence bundle manifest. This is all set up by the OSGi framework, and can be written portably accross frameworks (Aries JPA works on Equinox, Felix and Knopflerfish).

Aries JPA follows the JPA spec, and scans for all classes annotated with javax.persistence.Entity, which then appear in the managed classes list (as if they had been listed). Aries JPA will also always return true for PersistenceUnitInfo#excludeUnlistedClasses() to indicate that scanning for Entity classes is not needed. The reason that Aries JPA does this is that scanning for resources in OSGi is quite involved, and most JPA implementations prefer to avoid the extra complexity. It would be relatively easy for Aries JPA to include scanning for Hibernate Entity annotations (probably using a property in persistence.xml), and I would be happy to add the support. Another option is that I could help you start on an OSGI aware annotation scanner for hibernate, although that would be more work.

As for orm.xml and legacy mapping XML files, those will be loadable using the PersistenceUnitInfo#getClassLoader() if they are present.

In general, Aries JPA tries to make the OSGi framework look as much like Java EE as possible (although without a reliable TCCL). This is why Aries chose the container JPA route, and why it tends to support most JPA providers without too much effort on either side.

>One other concern is that org.hibernate.service.classloading.internal.ClassLoaderServiceImpl currently aggregates the overridenClassLoader (OsgiClassLoader) with core, TCCL, and getSystemClassLoader(). All ClassLoaders are iterated over until the class/resource is found. We might have to override this entire service to ensure that additional, conflicting ClassLoaders aren't automatically grabbed.

This could be an issue, depending on what the TCCL is. The SystemClassLoader is still the root of the OSGi classloader hierarchy, so that's ok. Assuming the overriddenClassLoader follows the search path I outlined above that will also ensure the correct visibility of Hibernate internals and the Entity classes (Aries JPA won't register a persistence bundle with a provider if it would cause an inconsistent class space). The only unknown is the TCCL, which *should* be ok most of the time, and can be worked around in applications if need be.

>Here's another one. In a container-managed environment (Aries, etc.), isn't there only one PersistenceUnit per runtime? I thought all app-provided units were aggregated into one. Does that change anything?

Aries JPA creates a separate PersistenceUnitInfo for each persistence unit defined in each persistence descriptor file (usually just persistence.xml). From memory, one of the Aries JPA tests has 27 persistence units in it, and all of them have separate persistence units and separate calls to PersistenceProvider.createContainerEntityManagerFactory(). There are two main reasons that Aries JPA does this.
1. Having separate persistence units for each persistence bundle allows maximum flexibility with classloading and prevents most versioning problems
2. Having separate persistence units for each persitence unit within a persistence bundle allows EntityManagerFactory services to be fully independent

>Apologies for the slew of questions -- you definitely have some great points that were overlooked. I just want to make sure we do it in the best way.

The questions really aren't a problem! I (and many people I know in the OSGi community) am really excited to see OSGi aware Hibernate, and I agree that we want it to be implemented so that it works as well as possible.