# HG changeset patch # User son # Date 1205414840 -10800 # Node ID deaaed5cedb777bc1ded7ed8518537a6169dee03 # Parent ed0c7cfb3666e3ea8da1c5d4cc7a8fd58689613f 6592751: EmbeddedFrame disposal is fragile and breaks clean AppContext termination Summary: AppContext.dispose() should be ready to get exceptions during disposal of toplevels. Also now we mark windows peers as destroyed when native object has been destroyed. Reviewed-by: art diff -r ed0c7cfb3666 -r deaaed5cedb7 jdk/src/share/classes/sun/awt/AppContext.java --- a/jdk/src/share/classes/sun/awt/AppContext.java Thu Mar 13 16:19:32 2008 +0300 +++ b/jdk/src/share/classes/sun/awt/AppContext.java Thu Mar 13 16:27:20 2008 +0300 @@ -1,5 +1,5 @@ /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,8 @@ import java.util.Map; import java.util.Set; import java.util.HashSet; +import java.util.logging.Level; +import java.util.logging.Logger; import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeListener; @@ -126,6 +128,7 @@ * @author Fred Ecks */ public final class AppContext { + private static final Logger log = Logger.getLogger("sun.awt.AppContext"); /* Since the contents of an AppContext are unique to each Java * session, this class should never be serialized. */ @@ -385,7 +388,13 @@ public void run() { Window[] windowsToDispose = Window.getOwnerlessWindows(); for (Window w : windowsToDispose) { - w.dispose(); + try { + w.dispose(); + } catch (Throwable t) { + if (log.isLoggable(Level.FINER)) { + log.log(Level.FINER, "exception occured while disposing app context", t); + } + } } AccessController.doPrivileged(new PrivilegedAction() { public Object run() { diff -r ed0c7cfb3666 -r deaaed5cedb7 jdk/src/windows/classes/sun/awt/windows/WObjectPeer.java --- a/jdk/src/windows/classes/sun/awt/windows/WObjectPeer.java Thu Mar 13 16:19:32 2008 +0300 +++ b/jdk/src/windows/classes/sun/awt/windows/WObjectPeer.java Thu Mar 13 16:27:20 2008 +0300 @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,8 +30,12 @@ initIDs(); } - long pData; // The Windows handle for the native widget. - Object target; // The associated AWT object. + // The Windows handle for the native widget. + long pData; + // if the native peer has been destroyed + boolean destroyed = false; + // The associated AWT object. + Object target; private volatile boolean disposed; diff -r ed0c7cfb3666 -r deaaed5cedb7 jdk/src/windows/native/sun/windows/awt.h --- a/jdk/src/windows/native/sun/windows/awt.h Thu Mar 13 16:19:32 2008 +0300 +++ b/jdk/src/windows/native/sun/windows/awt.h Thu Mar 13 16:27:20 2008 +0300 @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ JNI_CHECK_NULL_GOTO(peer, "peer", where); \ pData = JNI_GET_PDATA(peer); \ if (pData == NULL) { \ - JNU_ThrowNullPointerException(env, "null pData"); \ + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ goto where; \ } \ } @@ -63,7 +63,7 @@ JNI_CHECK_NULL_RETURN(peer, "peer"); \ pData = JNI_GET_PDATA(peer); \ if (pData == NULL) { \ - JNU_ThrowNullPointerException(env, "null pData"); \ + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ return; \ } \ } @@ -96,7 +96,7 @@ JNI_CHECK_NULL_RETURN_NULL(peer, "peer"); \ pData = JNI_GET_PDATA(peer); \ if (pData == NULL) { \ - JNU_ThrowNullPointerException(env, "null pData"); \ + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ return 0; \ } \ } @@ -105,16 +105,27 @@ JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val); \ pData = JNI_GET_PDATA(peer); \ if (pData == NULL) { \ - JNU_ThrowNullPointerException(env, "null pData"); \ + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ return val; \ } \ } +#define THROW_NULL_PDATA_IF_NOT_DESTROYED(peer) { \ + jboolean destroyed = JNI_GET_DESTROYED(peer); \ + if (destroyed != JNI_TRUE) { \ + JNU_ThrowNullPointerException(env, "null pData"); \ + } \ +} + #define JNI_GET_PDATA(peer) (PDATA) env->GetLongField(peer, AwtObject::pDataID) +#define JNI_GET_DESTROYED(peer) env->GetBooleanField(peer, AwtObject::destroyedID) #define JNI_SET_PDATA(peer, data) env->SetLongField(peer, \ - AwtObject::pDataID, \ - (jlong)data) + AwtObject::pDataID, \ + (jlong)data) +#define JNI_SET_DESTROYED(peer) env->SetBooleanField(peer, \ + AwtObject::destroyedID, \ + JNI_TRUE) /* /NEW JNI */ /* diff -r ed0c7cfb3666 -r deaaed5cedb7 jdk/src/windows/native/sun/windows/awt_Component.cpp --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp Thu Mar 13 16:19:32 2008 +0300 +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp Thu Mar 13 16:27:20 2008 +0300 @@ -5403,6 +5403,7 @@ if (m_peerObject) { env->SetLongField(m_peerObject, AwtComponent::hwndID, 0); JNI_SET_PDATA(m_peerObject, static_cast(NULL)); + JNI_SET_DESTROYED(m_peerObject); env->DeleteGlobalRef(m_peerObject); m_peerObject = NULL; } diff -r ed0c7cfb3666 -r deaaed5cedb7 jdk/src/windows/native/sun/windows/awt_Object.cpp --- a/jdk/src/windows/native/sun/windows/awt_Object.cpp Thu Mar 13 16:19:32 2008 +0300 +++ b/jdk/src/windows/native/sun/windows/awt_Object.cpp Thu Mar 13 16:27:20 2008 +0300 @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ */ jfieldID AwtObject::pDataID; +jfieldID AwtObject::destroyedID; jfieldID AwtObject::targetID; jclass AwtObject::wObjectPeerClass; jmethodID AwtObject::getPeerForTargetMID; @@ -223,6 +224,7 @@ AwtObject::wObjectPeerClass = (jclass)env->NewGlobalRef(cls); AwtObject::pDataID = env->GetFieldID(cls, "pData", "J"); + AwtObject::destroyedID = env->GetFieldID(cls, "destroyed", "Z"); AwtObject::targetID = env->GetFieldID(cls, "target", "Ljava/lang/Object;"); @@ -233,6 +235,7 @@ AwtObject::createErrorID = env->GetFieldID(cls, "createError", "Ljava/lang/Error;"); DASSERT(AwtObject::pDataID != NULL); + DASSERT(AwtObject::destroyedID != NULL); DASSERT(AwtObject::targetID != NULL); DASSERT(AwtObject::getPeerForTargetMID != NULL); DASSERT(AwtObject::createErrorID != NULL); diff -r ed0c7cfb3666 -r deaaed5cedb7 jdk/src/windows/native/sun/windows/awt_Object.h --- a/jdk/src/windows/native/sun/windows/awt_Object.h Thu Mar 13 16:19:32 2008 +0300 +++ b/jdk/src/windows/native/sun/windows/awt_Object.h Thu Mar 13 16:27:20 2008 +0300 @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,6 +51,7 @@ /* sun.awt.windows.WObjectPeer field and method ids */ static jfieldID pDataID; + static jfieldID destroyedID; static jfieldID targetID; static jmethodID getPeerForTargetMID;