Bug 88915
   Framework should ensure all files are closed on shutdown.
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java
index 86f7b8a..0dcc697 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java
@@ -167,7 +167,8 @@
 				fragments = null;
 				domain = null;
 			}
-		} else {
+		}
+		if (!exporting){
 			try {
 				this.bundledata.close();
 			} catch (IOException e) { // Do Nothing.
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoader.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoader.java
index 49a6257..535c3ab 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoader.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoader.java
@@ -323,13 +323,14 @@
 	 * Finds the class for a bundle.  This method is used for delegation by the bundle's classloader.
 	 */
 	public Class findClass(String name) throws ClassNotFoundException {
-		if (isClosed())
-			throw new ClassNotFoundException(name);
+		return findClass(name, true);
+	}
+
+	Class findClass(String name, boolean checkParent) throws ClassNotFoundException {
 		if (Debug.DEBUG && Debug.DEBUG_LOADER)
 			Debug.println("BundleLoader[" + this + "].loadBundleClass(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-		createClassLoader(); // make sure the classloader is created
 		// First check the parent classloader for system classes.
-		if (parent != null) {
+		if (checkParent && parent != null) {
 			if (Framework.STRICT_DELEGATION) {
 				if (name.startsWith(JAVA_CLASS))
 					// we want to throw ClassNotFoundExceptions if a java.* class cannot be loaded from the parent.
@@ -342,6 +343,8 @@
 				}
 		}
 
+		if (isClosed())
+			throw new ClassNotFoundException(name);
 		String pkgName = getPackageName(name);
 		Class result = null;
 		PackageSource source = findImportedSource(pkgName);
@@ -367,13 +370,12 @@
 	 * Finds the resource for a bundle.  This method is used for delegation by the bundle's classloader.
 	 */
 	public URL findResource(String name) {
-		if (isClosed())
-			return null;
-		if ((name.length() > 1) && (name.charAt(0) == '/')) /* if name has a leading slash */
-			name = name.substring(1); /* remove leading slash before search */
-		createClassLoader(); // make sure the classloader is created
+		return findResource(name, true);
+	}
+
+	URL findResource(String name, boolean checkParent) {
 		// First check the parent classloader for system resources, if it is a java resource.
-		if (parent != null) {
+		if (checkParent && parent != null) {
 			if (Framework.STRICT_DELEGATION) {
 				if (name.startsWith(JAVA_RESOURCE))
 					// we never delegate java resource requests past the parent
@@ -384,6 +386,11 @@
 					return result;
 			}
 		}
+		if (isClosed())
+			return null;
+		if ((name.length() > 1) && (name.charAt(0) == '/')) /* if name has a leading slash */
+			name = name.substring(1); /* remove leading slash before search */
+
 		String pkgName = getResourcePackageName(name);
 		URL result = null;
 		PackageSource source = findImportedSource(pkgName);
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoaderProxy.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoaderProxy.java
index db737b9..927b1e2 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoaderProxy.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoaderProxy.java
@@ -79,7 +79,6 @@
 		return stale;
 	}
 
-
 	public String toString() {
 		String symbolicName = bundle.getSymbolicName();
 		StringBuffer sb = new StringBuffer(symbolicName == null ? bundle.getLocation() : symbolicName);
@@ -131,7 +130,7 @@
 					BundleDescription[] dependents = dependent.getDependents();
 					if (dependents == null)
 						return;
-					for(int j = 0; j < dependents.length; j++)
+					for (int j = 0; j < dependents.length; j++)
 						dependentProxy.addRequirers(dependents[j], result);
 				}
 				return;
@@ -185,8 +184,7 @@
 		// check to see if it is a reexport
 		if (!export.isRoot()) {
 			pkgSource = new ReexportPackageSource(export.getName());
-		}
-		else {
+		} else {
 			// check to see if it is a filtered export
 			String includes = (String) export.getDirective(Constants.INCLUDE_DIRECTIVE);
 			String excludes = (String) export.getDirective(Constants.EXCLUDE_DIRECTIVE);
@@ -216,18 +214,16 @@
 				synchronized (pkgSource) {
 					pkgSources.add(pkgSource);
 				}
-		}
-		else {
+		} else {
 			// we are not storing the special case sources, but pkgSource == null this means this
 			// is a normal package source; get it and return it.
 			if (pkgSource == null)
 				pkgSource = getPackageSource(export.getName());
 		}
-				
+
 		return pkgSource;
 	}
 
-
 	class ReexportPackageSource extends PackageSource {
 		public ReexportPackageSource(String id) {
 			super(id);
@@ -242,15 +238,16 @@
 
 		public Class loadClass(String name) {
 			try {
-				return getBundleLoader().findClass(name);
-			}
-			catch(ClassNotFoundException e) {
+				return getBundleLoader().findClass(name, false);
+			} catch (ClassNotFoundException e) {
 				return null;
 			}
 		}
+
 		public URL getResource(String name) {
-			return getBundleLoader().findResource(name);
+			return getBundleLoader().findResource(name, false);
 		}
+
 		public Enumeration getResources(String name) throws IOException {
 			return getBundleLoader().findResources(name);
 		}
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/PackageAdminImpl.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/PackageAdminImpl.java
index c1ad69c..e581a80 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/PackageAdminImpl.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/PackageAdminImpl.java
@@ -270,7 +270,14 @@
 				throw new BundleException(Msg.OSGI_INTERNAL_ERROR); //$NON-NLS-1$
 			}
 			BundleLoaderProxy proxy = (BundleLoaderProxy) bundle.getUserObject();
-			BundleHost.closeBundleLoader(proxy);
+			if (proxy != null) {
+				BundleHost.closeBundleLoader(proxy);
+				try {
+					proxy.getBundleHost().getBundleData().close();
+				} catch (IOException e) {
+					// ignore
+				}
+			}
 		}
 	}
 
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java
index 8cf2e24..1388c14 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java
@@ -680,6 +680,12 @@
 					Debug.println("SLL: Trying to unload bundle " + bundle); //$NON-NLS-1$
 				}
 				bundle.refresh();
+				try {
+					// make sure we close all the bundle data objects
+					bundle.getBundleData().close();
+				} catch (IOException e) {
+					// ignore, we are shutting down anyway
+				}
 			}
 		}
 	}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractClassLoader.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractClassLoader.java
index f943fda..4095fce 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractClassLoader.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractClassLoader.java
@@ -42,11 +42,6 @@
 	protected String[] hostclasspath;
 
 	/**
-	 * Indicates this class loader is closed.
-	 */
-	protected boolean closed = false;
-
-	/**
 	 * BundleClassLoader constructor.
 	 * @param delegate The ClassLoaderDelegate for this bundle.
 	 * @param domain The ProtectionDomain for this bundle.
@@ -72,9 +67,6 @@
 	 * @throws ClassNotFoundException if the class is not found.
 	 */
 	protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
-		if (closed)
-			throw new ClassNotFoundException(name);
-
 		if (Debug.DEBUG && Debug.DEBUG_LOADER)
 			Debug.println("BundleClassLoader[" + delegate + "].loadClass(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
 		try {
@@ -122,9 +114,6 @@
 	 * @return The URL of the resource or null if it does not exist.
 	 */
 	public URL getResource(String name) {
-		if (closed) {
-			return null;
-		}
 		if (Debug.DEBUG && Debug.DEBUG_LOADER) {
 			Debug.println("BundleClassLoader[" + delegate + "].getResource(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 		}
@@ -198,15 +187,8 @@
 		return delegate;
 	}
 
-	/**
-	 * Closes this class loader.  After this method is called
-	 * loadClass will always throw ClassNotFoundException,
-	 * getResource, getResourceAsStream, and getResources will
-	 * return null.
-	 *
-	 */
 	public void close() {
-		closed = true;
+		// do nothing
 	}
 
 }
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/SystemBundleData.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/SystemBundleData.java
index dcff499..ef8d33b 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/SystemBundleData.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/SystemBundleData.java
@@ -198,14 +198,6 @@
 		return 0;
 	}
 
-	public void close() {
-		// do nothing
-	}
-
-	public void open() {
-		// do nothing
-	}
-
 	public void save() {
 		// do nothing
 	}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultClassLoader.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultClassLoader.java
index 7089ced..3571e08 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultClassLoader.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultClassLoader.java
@@ -437,18 +437,12 @@
 	 * Closes all the BundleFile objects for this BundleClassLoader.
 	 */
 	public void close() {
-		// do not close if we are shutting down
-		if (closed || hostdata.getAdaptor().isStopping())
-			return;
-
 		super.close();
 		if (classpathEntries != null) {
 			for (int i = 0; i < classpathEntries.length; i++) {
 				if (classpathEntries[i] != null) {
 					try {
-						if (classpathEntries[i].getBundleFile() != hostdata.getBaseBundleFile()) {
-							classpathEntries[i].getBundleFile().close();
-						}
+						classpathEntries[i].getBundleFile().close();
 					} catch (IOException e) {
 						hostdata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, hostdata.getBundle(), e);
 					}
@@ -583,9 +577,7 @@
 		protected void close() {
 			for (int i = 0; i < classpathEntries.length; i++) {
 				try {
-					if (classpathEntries[i].getBundleFile() != bundledata.getBaseBundleFile()) {
-						classpathEntries[i].getBundleFile().close();
-					}
+					classpathEntries[i].getBundleFile().close();
 				} catch (IOException e) {
 					bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), e);
 				}