6937053: RMI unmarshalling errors in ClientNotifForwarder cause silent failure
authordsamersoff
Thu, 20 Dec 2012 16:56:33 +0400
changeset 14912 e6fc057a8011
parent 14911 404c8c3c91ee
child 14913 7274b8c518e8
6937053: RMI unmarshalling errors in ClientNotifForwarder cause silent failure Summary: the catch block in the fetchNotifs() method is extended to expect UnmarshalException Reviewed-by: emcmanus Contributed-by: jaroslav.bachorik@oracle.com
jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java
--- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java	Thu Dec 20 16:02:42 2012 +0400
+++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java	Thu Dec 20 16:56:33 2012 +0400
@@ -51,6 +51,7 @@
 
 import com.sun.jmx.remote.util.ClassLogger;
 import com.sun.jmx.remote.util.EnvHelp;
+import java.rmi.UnmarshalException;
 
 
 public abstract class ClientNotifForwarder {
@@ -594,10 +595,7 @@
                 }
 
                 return nr;
-            } catch (ClassNotFoundException e) {
-                logger.trace("NotifFetcher.fetchNotifs", e);
-                return fetchOneNotif();
-            } catch (NotSerializableException e) {
+            } catch (ClassNotFoundException | NotSerializableException | UnmarshalException e) {
                 logger.trace("NotifFetcher.fetchNotifs", e);
                 return fetchOneNotif();
             } catch (IOException ioe) {
@@ -619,17 +617,18 @@
            timeout.  This allows us to skip sequence numbers for
            notifications that don't match our filters.  Then we ask
            for one notification.  If that produces a
-           ClassNotFoundException or a NotSerializableException, we
-           increase our sequence number and ask again.  Eventually we
-           will either get a successful notification, or a return with
-           0 notifications.  In either case we can return a
+           ClassNotFoundException, NotSerializableException or
+           UnmarshalException, we increase our sequence number and ask again.
+           Eventually we will either get a successful notification, or a
+           return with 0 notifications.  In either case we can return a
            NotificationResult.  This algorithm works (albeit less
            well) even if the server implementation doesn't optimize a
            request for 0 notifications to skip sequence numbers for
            notifications that don't match our filters.
 
-           If we had at least one ClassNotFoundException, then we
-           must emit a JMXConnectionNotification.LOST_NOTIFS.
+           If we had at least one
+           ClassNotFoundException/NotSerializableException/UnmarshalException,
+           then we must emit a JMXConnectionNotification.LOST_NOTIFS.
         */
         private NotificationResult fetchOneNotif() {
             ClientNotifForwarder cnf = ClientNotifForwarder.this;
@@ -668,23 +667,20 @@
                 try {
                     // 1 notif to skip possible missing class
                     result = cnf.fetchNotifs(startSequenceNumber, 1, 0L);
+                } catch (ClassNotFoundException | NotSerializableException | UnmarshalException e) {
+                    logger.warning("NotifFetcher.fetchOneNotif",
+                                   "Failed to deserialize a notification: "+e.toString());
+                    if (logger.traceOn()) {
+                        logger.trace("NotifFetcher.fetchOneNotif",
+                                     "Failed to deserialize a notification.", e);
+                    }
+
+                    notFoundCount++;
+                    startSequenceNumber++;
                 } catch (Exception e) {
-                    if (e instanceof ClassNotFoundException
-                        || e instanceof NotSerializableException) {
-                        logger.warning("NotifFetcher.fetchOneNotif",
-                                     "Failed to deserialize a notification: "+e.toString());
-                        if (logger.traceOn()) {
-                            logger.trace("NotifFetcher.fetchOneNotif",
-                                         "Failed to deserialize a notification.", e);
-                        }
-
-                        notFoundCount++;
-                        startSequenceNumber++;
-                    } else {
-                        if (!shouldStop())
-                            logger.trace("NotifFetcher.fetchOneNotif", e);
-                        return null;
-                    }
+                    if (!shouldStop())
+                        logger.trace("NotifFetcher.fetchOneNotif", e);
+                    return null;
                 }
             }
 
@@ -692,7 +688,7 @@
                 final String msg =
                     "Dropped " + notFoundCount + " notification" +
                     (notFoundCount == 1 ? "" : "s") +
-                    " because classes were missing locally";
+                    " because classes were missing locally or incompatible";
                 lostNotifs(msg, notFoundCount);
                 // Even if result.getEarliestSequenceNumber() is now greater than
                 // it was initially, meaning some notifs have been dropped