aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Ross2012-08-20 09:35:57 (EDT)
committerThomas Watson2012-08-20 09:35:57 (EDT)
commit464ea4795b2c38ab0f297f3713955b6251f08ee3 (patch)
tree808c972116aa141aeb6023ffa12e1cfb38c084dc
parentb230e488d47b8a80960b518f4e79bc5f18c7405e (diff)
downloadrt.equinox.framework-464ea4795b2c38ab0f297f3713955b6251f08ee3.zip
rt.equinox.framework-464ea4795b2c38ab0f297f3713955b6251f08ee3.tar.gz
rt.equinox.framework-464ea4795b2c38ab0f297f3713955b6251f08ee3.tar.bz2
Bug 383338 - Null Pointer Exception at JVM shutdownv20120820-133557M20120822-1200M20120822-1000
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java13
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorage.java27
2 files changed, 22 insertions, 18 deletions
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java
index d3aeaf6..617db7f 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java
@@ -56,26 +56,26 @@ public class Framework implements EventPublisher, Runnable {
private static String JAVASE = "JavaSE-"; //$NON-NLS-1$
private static String PROFILE_EXT = ".profile"; //$NON-NLS-1$
/** FrameworkAdaptor specific functions. */
- protected FrameworkAdaptor adaptor;
+ protected volatile FrameworkAdaptor adaptor;
/** Framework properties object. A reference to the
* System.getProperies() object. The properties from
* the adaptor will be merged into these properties.
*/
protected Properties properties;
/** Has the framework been started */
- protected boolean active;
+ protected volatile boolean active;
/** Event indicating the reason for shutdown*/
private FrameworkEvent[] shutdownEvent;
/** The bundles installed in the framework */
protected BundleRepository bundles;
/** Package Admin object. This object manages the exported packages. */
- protected PackageAdminImpl packageAdmin;
+ protected volatile PackageAdminImpl packageAdmin;
/** PermissionAdmin and ConditionalPermissionAdmin impl. This object manages the bundle permissions. */
protected SecurityAdmin securityAdmin;
/** Startlevel object. This object manages the framework and bundle startlevels */
protected StartLevelManager startLevelManager;
/** The ServiceRegistry */
- private ServiceRegistry serviceRegistry;
+ private volatile ServiceRegistry serviceRegistry;
private final int BSN_VERSION;
private static final int BSN_VERSION_SINGLE = 1;
private static final int BSN_VERSION_MULTIPLE = 2;
@@ -104,7 +104,7 @@ public class Framework implements EventPublisher, Runnable {
static final String findHookName = FindHook.class.getName();
static final String collisionHookName = CollisionHook.class.getName();
/** EventManager for event delivery. */
- protected EventManager eventManager;
+ protected volatile EventManager eventManager;
/* Reservation object for install synchronization */
private Map<String, Thread> installLock;
/** System Bundle object */
@@ -121,7 +121,7 @@ public class Framework implements EventPublisher, Runnable {
* The AliasMapper used to alias OS Names.
*/
protected static AliasMapper aliasMapper = new AliasMapper();
- SecureAction secureAction = AccessController.doPrivileged(SecureAction.createSecureAction());
+ static final SecureAction secureAction = AccessController.doPrivileged(SecureAction.createSecureAction());
// cache of AdminPermissions keyed by Bundle ID
private final Map<Long, Map<String, AdminPermission>> adminPermissions = new HashMap<Long, Map<String, AdminPermission>>();
@@ -616,7 +616,6 @@ public class Framework implements EventPublisher, Runnable {
eventManager.close();
eventManager = null;
}
- secureAction = null;
packageAdmin = null;
adaptor = null;
uninstallURLStreamHandlerFactory();
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorage.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorage.java
index cd68456..982b816 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorage.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorage.java
@@ -912,7 +912,7 @@ public class BaseStorage implements SynchronousBundleListener {
this.context = fwContext;
// System property can be set to enable state saver or not.
if (Boolean.valueOf(FrameworkProperties.getProperty(BaseStorage.PROP_ENABLE_STATE_SAVER, "true")).booleanValue()) //$NON-NLS-1$
- stateSaver = new StateSaver();
+ stateSaver = new StateSaver(adaptor.getState());
}
@@ -1249,7 +1249,13 @@ public class BaseStorage implements SynchronousBundleListener {
private Thread runningThread = null;
private Thread shutdownHook = null;
- StateSaver() {
+ // Bug 383338. Pass the BaseAdaptor state as a constructor argument and
+ // reuse rather than call adaptor.getState(), and risk an NPE from
+ // Framework due to a null ServiceRegistry, each time a lock is desired.
+ private final State lock;
+
+ StateSaver(State lock) {
+ this.lock = lock;
String prop = FrameworkProperties.getProperty("eclipse.stateSaveDelayInterval"); //$NON-NLS-1$
long delayValue = 30000; // 30 seconds.
long maxDelayValue = 1800000; // 30 minutes.
@@ -1272,8 +1278,7 @@ public class BaseStorage implements SynchronousBundleListener {
}
public void run() {
- State systemState = adaptor.getState();
- synchronized (systemState) {
+ synchronized (lock) {
long firstSaveTime = lastSaveTime;
long curSaveTime = 0;
long delayTime;
@@ -1289,7 +1294,7 @@ public class BaseStorage implements SynchronousBundleListener {
// wait for other save requests
try {
if (!shutdown)
- systemState.wait(delayTime);
+ lock.wait(delayTime);
} catch (InterruptedException ie) {
// force break from do/while loops
curSaveTime = lastSaveTime;
@@ -1312,12 +1317,13 @@ public class BaseStorage implements SynchronousBundleListener {
}
void shutdown() {
- State systemState = adaptor.getState();
- Thread joinWith = null;
- synchronized (systemState) {
+ Thread joinWith;
+ synchronized (lock) {
+ if (shutdown)
+ return; // Don't shutdown more than once. Bug 383338.
shutdown = true;
joinWith = runningThread;
- systemState.notifyAll(); // To wakeup sleeping thread.
+ lock.notifyAll(); // To wakeup sleeping thread.
}
try {
if (joinWith != null) {
@@ -1337,8 +1343,7 @@ public class BaseStorage implements SynchronousBundleListener {
}
void requestSave() {
- final State systemState = adaptor.getState();
- synchronized (systemState) {
+ synchronized (lock) {
if (shutdown)
return; // do not start another thread if we have already shutdown
if (delay_interval == 0) {