More attempts to make resolver state handling more consistent. (FELIX-851)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@737912 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
index 80ef6fa..d532af7 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -33,7 +33,8 @@
class BundleImpl implements Bundle
{
- private final Felix m_felix;
+ // No one should use this field directly, use getFramework() instead.
+ private final Felix _m_felix;
private final BundleArchive m_archive;
private IModule[] m_modules = new IModule[0];
@@ -61,7 +62,7 @@
BundleImpl(Felix felix, BundleArchive archive) throws Exception
{
- m_felix = felix;
+ _m_felix = felix;
m_archive = archive;
m_state = Bundle.INSTALLED;
m_stale = false;
@@ -74,7 +75,6 @@
{
IModule module = createModule();
addModule(module);
- m_felix.getResolverState().addModule(module);
}
}
@@ -84,19 +84,24 @@
// not access the field directly.
Felix getFramework()
{
- return m_felix;
+ return _m_felix;
+ }
+
+ synchronized void dispose()
+ {
+ // Remove the bundle's associated modules from the resolver state
+ // and close them.
+ for (int i = 0; i < m_modules.length; i++)
+ {
+ getFramework().getResolverState().removeModule(m_modules[i]);
+ ((ModuleImpl) m_modules[i]).close();
+ }
}
synchronized void refresh() throws Exception
{
- // We are refreshing the bundle. First, we must remove all existing
- // modules from the resolver state and close them. Closing the modules
- // is important, since we will likely be deleting their associated files.
- for (int i = 0; i < m_modules.length; i++)
- {
- m_felix.getResolverState().removeModule(m_modules[i]);
- ((ModuleImpl) m_modules[i]).close();
- }
+ // Dispose of the current modules.
+ dispose();
// Now we will purge all old revisions, only keeping the newest one.
m_archive.purge();
@@ -106,7 +111,6 @@
m_modules = new IModule[0];
final IModule module = createModule();
addModule(module);
- m_felix.getResolverState().addModule(module);
m_state = Bundle.INSTALLED;
m_stale = false;
m_cachedHeaders.clear();
@@ -899,7 +903,6 @@
m_archive.revise(location, is);
IModule module = createModule();
addModule(module);
- m_felix.addModule(module);
}
synchronized boolean rollbackRevise() throws Exception
@@ -918,7 +921,7 @@
{
sp.checkBundle(this);
}
- module.setSecurityContext(new BundleProtectionDomain(m_felix, this));
+ module.setSecurityContext(new BundleProtectionDomain(getFramework(), this));
((ModuleImpl) module).setBundle(this);
@@ -926,6 +929,10 @@
System.arraycopy(m_modules, 0, dest, 0, m_modules.length);
dest[m_modules.length] = module;
m_modules = dest;
+
+ // Now that the module is added to the bundle, we can update
+ // the resolver's module state.
+ getFramework().getResolverState().addModule(module);
}
private IModule createModule() throws Exception
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index 32050f4..aa9983a 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -297,7 +297,6 @@
// definition for creating the system bundle module.
m_extensionManager = new ExtensionManager(m_logger, m_configMap);
addModule(m_extensionManager.getModule());
- m_resolverState.addModule(getCurrentModule());
}
Logger getLogger()
@@ -3121,15 +3120,8 @@
// because this method is only called during shutdown or a
// refresh operation and these are already guarded by locks.
- // Remove the bundle's associated modules from
- // the module manager.
- IModule[] modules = bundle.getModules();
- for (int i = 0; i < modules.length; i++)
- {
- m_resolverState.removeModule(modules[i]);
- }
-
- // Remove the bundle from the cache.
+ // Remove the bundle from memory and the cache.
+ bundle.dispose();
m_cache.remove(m_cache.getArchive(bundle.getBundleId()));
}
@@ -3594,34 +3586,12 @@
// Shutdown event dispatching queue.
EventDispatcher.shutdown();
- // Remove all bundles from the module factory so that any
- // open resources will be closed.
- Bundle[] bundles = getBundles();
- for (int i = 0; i < bundles.length; i++)
- {
- BundleImpl bundle = (BundleImpl) bundles[i];
- IModule[] modules = bundle.getModules();
- for (int j = 0; j < modules.length; j++)
- {
- try
- {
- m_resolverState.removeModule(modules[j]);
- }
- catch (Exception ex)
- {
- m_logger.log(Logger.LOG_ERROR,
- "Unable to clean up " + bundle._getLocation(), ex);
- }
- }
- }
-
// Since there may be updated and uninstalled bundles that
// have not been refreshed, we will take care of refreshing
// them during shutdown.
- // First loop through all bundled and purge old revisions
- // from updated bundles.
- bundles = getBundles();
+ // Refresh all updated bundles.
+ Bundle[] bundles = getBundles();
for (int i = 0; i < bundles.length; i++)
{
BundleImpl bundle = (BundleImpl) bundles[i];
@@ -3640,7 +3610,7 @@
}
}
- // Next garbage collection any uninstalled bundles.
+ // Garbage collect uninstalled bundles.
for (int i = 0;
(m_uninstalledBundles != null) && (i < m_uninstalledBundles.length);
i++)
@@ -3658,7 +3628,14 @@
}
}
- // Next, stop all system bundle activators.
+ // Dispose of the bundles to close their associated contents.
+ bundles = getBundles();
+ for (int i = 0; i < bundles.length; i++)
+ {
+ ((BundleImpl) bundles[i]).dispose();
+ }
+
+ // Stop all system bundle activators.
for (int i = 0; i < m_activatorList.size(); i++)
{
try
@@ -3733,16 +3710,14 @@
// current state.
if (m_bundle.getState() == Bundle.UNINSTALLED)
{
- // This physically removes the bundle from memory
- // as well as the bundle cache.
garbageCollectBundle(m_bundle);
m_bundle = null;
}
else
{
- // This physically removes all old bundle modules from
- // from memory and all old revisions from disk. It only
- // maintains the newest version in the bundle cache.
+ // This removes all old bundle modules from memory and
+ // all old revisions from disk. It only maintains the
+ // newest version in the bundle cache.
refreshBundle(m_bundle);
}
}