Bug 64134 NPE in JavaRuntime on Workbench Exit.
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/ADAPTOR.MF b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/ADAPTOR.MF
index d427999..c50371a 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/ADAPTOR.MF
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/ADAPTOR.MF
@@ -16,8 +16,7 @@
  org.eclipse.osgi.service.runnable,
  org.eclipse.osgi.service.urlconversion,
  org.eclipse.core.runtime.adaptor.testsupport,
- org.eclipse.osgi.service.localization,
- org.eclipse.core.runtime.adaptor
+ org.eclipse.osgi.service.localization
 Export-Service: 
  org.eclipse.osgi.framework.log.FrameworkLog,
  org.eclipse.osgi.service.environment.EnvironmentInfo,
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptor.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptor.java
index f9f857b..ae17931 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptor.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptor.java
@@ -72,7 +72,7 @@
 	private String installURL = null;
 	private boolean exitOnError = true;
 	private BundleStopper stopper;
-	
+
 	/*
 	 * Should be instantiated only by the framework (through reflection). 
 	 */
@@ -121,10 +121,10 @@
 		readHeaders();
 		checkLocationAndReinitialize();
 		File stateLocation = LocationManager.getConfigurationFile(LocationManager.STATE_FILE);
-		if(!stateLocation.isFile()) { //NOTE this check is redundant since it is done in StateManager, however it is more convenient to have it here 
+		if (!stateLocation.isFile()) { //NOTE this check is redundant since it is done in StateManager, however it is more convenient to have it here 
 			Location parentConfiguration = null;
 			if ((parentConfiguration = LocationManager.getConfigurationLocation().getParentLocation()) != null) {
-				stateLocation = new File(parentConfiguration.getURL().getFile(), FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + '/' + LocationManager.STATE_FILE);				
+				stateLocation = new File(parentConfiguration.getURL().getFile(), FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + '/' + LocationManager.STATE_FILE);
 			}
 		}
 		stateManager = new StateManager(stateLocation, timeStamp);
@@ -158,7 +158,7 @@
 			File stateLocation = LocationManager.getConfigurationFile(LocationManager.STATE_FILE);
 			stateManager.shutdown(stateLocation); //$NON-NLS-1$
 		} catch (IOException e) {
-			frameworkLog.log(new FrameworkEvent(FrameworkEvent.ERROR,context.getBundle(),e));
+			frameworkLog.log(new FrameworkEvent(FrameworkEvent.ERROR, context.getBundle(), e));
 		}
 	}
 
@@ -185,14 +185,14 @@
 	private void readHeaders() {
 		InputStream bundleDataStream = findBundleDataFile();
 		if (bundleDataStream == null)
-			return;			
+			return;
 
 		try {
 			DataInputStream in = new DataInputStream(new BufferedInputStream(bundleDataStream));
 			try {
 				if (in.readByte() == BUNDLEDATA_VERSION) {
 					timeStamp = in.readLong();
-					installURL = in.readUTF();					
+					installURL = in.readUTF();
 					initialBundleStartLevel = in.readInt();
 					nextId = in.readLong();
 				}
@@ -250,8 +250,6 @@
 		register(CommandProvider.class.getName(), new EclipseCommandProvider(context), bundle);
 		register(FrameworkLog.class.getName(), getFrameworkLog(), bundle);
 		register(org.eclipse.osgi.service.localization.BundleLocalization.class.getName(), new BundleLocalizationImpl(), bundle);
-		stopper = new BundleStopper();
-		register(BundleStopper.class.getName(), stopper, bundle);
 		registerEndorsedXMLParser();
 	}
 
@@ -266,7 +264,7 @@
 		StateManager.DEBUG_PLATFORM_ADMIN = options.getBooleanOption(OPTION_PLATFORM_ADMIN, false);
 		StateManager.DEBUG_PLATFORM_ADMIN_RESOLVER = options.getBooleanOption(OPTION_PLATFORM_ADMIN_RESOLVER, false);
 		PluginConverterImpl.DEBUG = options.getBooleanOption(OPTION_CONVERTER, false);
-		BasicLocation.DEBUG =  options.getBooleanOption(OPTION_LOCATION, false);
+		BasicLocation.DEBUG = options.getBooleanOption(OPTION_LOCATION, false);
 	}
 
 	private void registerEndorsedXMLParser() {
@@ -326,7 +324,7 @@
 
 	private InputStream findBundleDataFile() {
 		File metadata = LocationManager.getConfigurationFile(LocationManager.BUNDLE_DATA_FILE);
-		InputStream bundleDataStream = null; 
+		InputStream bundleDataStream = null;
 		if (metadata.isFile()) {
 			try {
 				bundleDataStream = new FileInputStream(metadata);
@@ -336,17 +334,18 @@
 		} else {
 			Location parentConfiguration = null;
 			if ((parentConfiguration = LocationManager.getConfigurationLocation().getParentLocation()) != null) {
-				 try {
+				try {
 					bundleDataStream = new URL(parentConfiguration.getURL(), FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + '/' + LocationManager.BUNDLE_DATA_FILE).openStream();
 				} catch (MalformedURLException e1) {
 					//This will not happen since all the URLs are derived by us and we are GODS!
 				} catch (IOException e1) {
 					//That's ok we will regenerate the .bundleData
-				}				
+				}
 			}
 		}
 		return bundleDataStream;
 	}
+
 	/**
 	 * @see org.eclipse.osgi.framework.adaptor.FrameworkAdaptor#getInstalledBundles()
 	 */
@@ -354,7 +353,7 @@
 		InputStream bundleDataStream = findBundleDataFile();
 		if (bundleDataStream == null)
 			return null;
-		
+
 		try {
 			DataInputStream in = new DataInputStream(new BufferedInputStream(bundleDataStream));
 			try {
@@ -534,7 +533,7 @@
 				out.close();
 			}
 		} catch (IOException e) {
-			frameworkLog.log(new FrameworkEvent(FrameworkEvent.ERROR,context.getBundle(),e));
+			frameworkLog.log(new FrameworkEvent(FrameworkEvent.ERROR, context.getBundle(), e));
 		}
 	}
 
@@ -548,6 +547,7 @@
 
 	public void frameworkStopping(BundleContext context) {
 		super.frameworkStopping(context);
+		stopper = new BundleStopper();
 		stopper.stopBundles();
 	}
 
@@ -564,12 +564,10 @@
 			try {
 				error.printStackTrace();
 				t.printStackTrace();
-			}
-			catch (Throwable t1) {
+			} catch (Throwable t1) {
 				// if we fail that then we are beyond help.
 			}
-		}
-		finally {
+		} finally {
 			// do the exit outside the try block just incase another runtime error was thrown while logging
 			if (exitOnError)
 				System.exit(13);
@@ -579,4 +577,8 @@
 	protected void setLog(FrameworkLog log) {
 		frameworkLog = log;
 	}
+
+	public BundleStopper getBundleStopper() {
+		return stopper;
+	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptorMessages.properties b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptorMessages.properties
index 61f27ba..c61aeab 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptorMessages.properties
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptorMessages.properties
@@ -69,6 +69,7 @@
 ECLIPSE_CLASSLOADER_CONCURRENT_STARTUP=While loading class "{1}", thread "{0}" timed out waiting ({4}ms) for thread "{2}" to finish starting bundle "{3}". To avoid deadlock, thread "{0}" is proceeding but "{1}" may not be fully initialized.
 ECLIPSE_CLASSLOADER_ACTIVATION=An error occured while automatically activating bundle {0} ({1}).
 ECLIPSE_CLASSLOADER_GENERATED_EXCEPTION=Generated exception.
+ECLIPSE_CLASSLOADER_ALREADY_STOPPED= The class \"{0}\" cannot be loaded because the system is shutting down and the plug-in \"{1}\" has already been stopped.
 
 #BundleStopper messages
 ECLIPSE_BUNDLESTOPPER_CYCLES_FOUND=Error stopping bundles. Cycle(s) found: {0}.
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseClassLoader.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseClassLoader.java
index ecc2059..beeec2c 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseClassLoader.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseClassLoader.java
@@ -138,10 +138,15 @@
 	/**
 	 * Determines if for loading the given class we should activate the bundle. 
 	 */
-	private boolean shouldActivateFor(String className) {
+	private boolean shouldActivateFor(String className) throws ClassNotFoundException {
 		//Don't reactivate on shut down
-		if (hostdata.getAdaptor().isStopping())
-			return false;
+		if (hostdata.getAdaptor().isStopping()) {
+			BundleStopper stopper = EclipseAdaptor.getDefault().getBundleStopper();
+			if (stopper != null && stopper.isStopped(hostdata.getSymbolicName())) {
+				String message = EclipseAdaptorMsg.formatter.getString("ECLIPSE_CLASSLOADER_ALREADY_STOPPED", className, hostdata.getSymbolicName()); //$NON-NLS-1$
+				throw new ClassNotFoundException(message);
+			}
+		}
 		boolean autoStart = ((EclipseBundleData) hostdata).isAutoStart();
 		String[] autoStartExceptions = ((EclipseBundleData) hostdata).getAutoStartExceptions();
 		// no exceptions, it is easy to figure it out