[HHH-10346] [ENTESB-4495] Hibernate and Bundle ClassLoaders out of sync on Bundle Refresh

This commit is contained in:
Guillaume Nodet 2015-12-01 08:51:31 +01:00 committed by Brett Meyer
parent d0831d4511
commit 0af33132a4
2 changed files with 27 additions and 1 deletions

View File

@ -34,6 +34,8 @@ import org.hibernate.internal.util.ClassLoaderHelper;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceRegistration;
@ -95,6 +97,14 @@ public class HibernateBundleActivator implements BundleActivator {
new OsgiSessionFactoryService( osgiClassLoader, osgiJtaPlatform, osgiServiceUtil ),
new Hashtable()
);
context.addBundleListener(new BundleListener() {
@Override
public void bundleChanged(BundleEvent bundleEvent) {
if (bundleEvent.getType() == BundleEvent.UNRESOLVED)
osgiClassLoader.removeBundle(bundleEvent.getBundle());
}
});
}
@Override

View File

@ -35,6 +35,8 @@ import java.util.Set;
import org.hibernate.service.spi.Stoppable;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleReference;
import org.osgi.framework.wiring.BundleWiring;
/**
* Custom OSGI ClassLoader helper which knows all the "interesting"
@ -214,7 +216,7 @@ public class OsgiClassLoader extends ClassLoader implements Stoppable {
* @param bundle The Bundle to add
*/
public void addBundle( Bundle bundle ) {
bundles.add( bundle );
addClassLoader( bundle.adapt(BundleWiring.class).getClassLoader() );
}
@Override
@ -225,4 +227,18 @@ public class OsgiClassLoader extends ClassLoader implements Stoppable {
resourceCache.clear();
}
public void removeBundle(Bundle bundle) {
List<ClassLoader> toRemove = new ArrayList<ClassLoader>();
for (ClassLoader cl : classLoaders) {
if (cl instanceof BundleReference) {
Bundle b = ((BundleReference) cl).getBundle();
if (b == bundle) {
toRemove.add(cl);
}
}
}
if (classLoaders.removeAll(toRemove)) {
clear();
}
}
}