[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 577af3b324
commit d1e93c4a1b
2 changed files with 28 additions and 2 deletions

View File

@ -34,6 +34,8 @@ import org.hibernate.ejb.HibernatePersistence;
import org.hibernate.internal.util.ClassLoaderHelper; import org.hibernate.internal.util.ClassLoaderHelper;
import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
import org.osgi.framework.FrameworkUtil; import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceRegistration; import org.osgi.framework.ServiceRegistration;
@ -66,7 +68,7 @@ public class HibernateBundleActivator implements BundleActivator {
@Override @Override
public void start(BundleContext context) throws Exception { public void start(BundleContext context) throws Exception {
OsgiClassLoader osgiClassLoader = new OsgiClassLoader(); final OsgiClassLoader osgiClassLoader = new OsgiClassLoader();
osgiClassLoader.addBundle( FrameworkUtil.getBundle( Session.class ) ); osgiClassLoader.addBundle( FrameworkUtil.getBundle( Session.class ) );
osgiClassLoader.addBundle( FrameworkUtil.getBundle( HibernatePersistence.class ) ); osgiClassLoader.addBundle( FrameworkUtil.getBundle( HibernatePersistence.class ) );
ClassLoaderHelper.overridenClassLoader = osgiClassLoader; ClassLoaderHelper.overridenClassLoader = osgiClassLoader;
@ -82,6 +84,14 @@ public class HibernateBundleActivator implements BundleActivator {
sessionFactoryService = context.registerService( SessionFactory.class.getName(), sessionFactoryService = context.registerService( SessionFactory.class.getName(),
new OsgiSessionFactoryService( osgiClassLoader, osgiJtaPlatform, context ), new Hashtable()); new OsgiSessionFactoryService( osgiClassLoader, osgiJtaPlatform, context ), new Hashtable());
context.addBundleListener(new BundleListener() {
@Override
public void bundleChanged(BundleEvent bundleEvent) {
if (bundleEvent.getType() == BundleEvent.UNRESOLVED)
osgiClassLoader.removeBundle(bundleEvent.getBundle());
}
});
} }
@Override @Override

View File

@ -34,6 +34,8 @@ import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import org.osgi.framework.Bundle; 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" * Custom OSGI ClassLoader helper which knows all the "interesting"
@ -204,7 +206,7 @@ public class OsgiClassLoader extends ClassLoader {
} }
public void addBundle( Bundle bundle ) { public void addBundle( Bundle bundle ) {
bundles.add( bundle ); addClassLoader( bundle.adapt(BundleWiring.class).getClassLoader() );
} }
public void clear() { public void clear() {
@ -212,4 +214,18 @@ public class OsgiClassLoader extends ClassLoader {
resourceCache.clear(); 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();
}
}
} }