From d1e93c4a1bdb26a80c9490c2256e625a5810a7ca Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Tue, 1 Dec 2015 08:51:31 +0100 Subject: [PATCH] [HHH-10346] [ENTESB-4495] Hibernate and Bundle ClassLoaders out of sync on Bundle Refresh --- .../osgi/HibernateBundleActivator.java | 12 +++++++++++- .../org/hibernate/osgi/OsgiClassLoader.java | 18 +++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/hibernate-osgi/src/main/java/org/hibernate/osgi/HibernateBundleActivator.java b/hibernate-osgi/src/main/java/org/hibernate/osgi/HibernateBundleActivator.java index bbe6089365..72eda9fd8f 100644 --- a/hibernate-osgi/src/main/java/org/hibernate/osgi/HibernateBundleActivator.java +++ b/hibernate-osgi/src/main/java/org/hibernate/osgi/HibernateBundleActivator.java @@ -34,6 +34,8 @@ import org.hibernate.ejb.HibernatePersistence; import org.hibernate.internal.util.ClassLoaderHelper; 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; @@ -66,7 +68,7 @@ public class HibernateBundleActivator implements BundleActivator { @Override 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( HibernatePersistence.class ) ); ClassLoaderHelper.overridenClassLoader = osgiClassLoader; @@ -82,6 +84,14 @@ public class HibernateBundleActivator implements BundleActivator { sessionFactoryService = context.registerService( SessionFactory.class.getName(), 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 diff --git a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiClassLoader.java b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiClassLoader.java index e1dc63f075..df77789489 100644 --- a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiClassLoader.java +++ b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiClassLoader.java @@ -34,6 +34,8 @@ import java.util.NoSuchElementException; import java.util.Set; 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" @@ -204,7 +206,7 @@ public class OsgiClassLoader extends ClassLoader { } public void addBundle( Bundle bundle ) { - bundles.add( bundle ); + addClassLoader( bundle.adapt(BundleWiring.class).getClassLoader() ); } public void clear() { @@ -212,4 +214,18 @@ public class OsgiClassLoader extends ClassLoader { resourceCache.clear(); } + public void removeBundle(Bundle bundle) { + List toRemove = new ArrayList(); + for (ClassLoader cl : classLoaders) { + if (cl instanceof BundleReference) { + Bundle b = ((BundleReference) cl).getBundle(); + if (b == bundle) { + toRemove.add(cl); + } + } + } + if (classLoaders.removeAll(toRemove)) { + clear(); + } + } }