提交 0c612fe0 编写于 作者: D dsamersoff

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
上级 ee8efe9a
...@@ -51,6 +51,7 @@ import javax.management.remote.TargetedNotification; ...@@ -51,6 +51,7 @@ import javax.management.remote.TargetedNotification;
import com.sun.jmx.remote.util.ClassLogger; import com.sun.jmx.remote.util.ClassLogger;
import com.sun.jmx.remote.util.EnvHelp; import com.sun.jmx.remote.util.EnvHelp;
import java.rmi.UnmarshalException;
public abstract class ClientNotifForwarder { public abstract class ClientNotifForwarder {
...@@ -594,10 +595,7 @@ public abstract class ClientNotifForwarder { ...@@ -594,10 +595,7 @@ public abstract class ClientNotifForwarder {
} }
return nr; return nr;
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException | NotSerializableException | UnmarshalException e) {
logger.trace("NotifFetcher.fetchNotifs", e);
return fetchOneNotif();
} catch (NotSerializableException e) {
logger.trace("NotifFetcher.fetchNotifs", e); logger.trace("NotifFetcher.fetchNotifs", e);
return fetchOneNotif(); return fetchOneNotif();
} catch (IOException ioe) { } catch (IOException ioe) {
...@@ -619,17 +617,18 @@ public abstract class ClientNotifForwarder { ...@@ -619,17 +617,18 @@ public abstract class ClientNotifForwarder {
timeout. This allows us to skip sequence numbers for timeout. This allows us to skip sequence numbers for
notifications that don't match our filters. Then we ask notifications that don't match our filters. Then we ask
for one notification. If that produces a for one notification. If that produces a
ClassNotFoundException or a NotSerializableException, we ClassNotFoundException, NotSerializableException or
increase our sequence number and ask again. Eventually we UnmarshalException, we increase our sequence number and ask again.
will either get a successful notification, or a return with Eventually we will either get a successful notification, or a
0 notifications. In either case we can return a return with 0 notifications. In either case we can return a
NotificationResult. This algorithm works (albeit less NotificationResult. This algorithm works (albeit less
well) even if the server implementation doesn't optimize a well) even if the server implementation doesn't optimize a
request for 0 notifications to skip sequence numbers for request for 0 notifications to skip sequence numbers for
notifications that don't match our filters. notifications that don't match our filters.
If we had at least one ClassNotFoundException, then we If we had at least one
must emit a JMXConnectionNotification.LOST_NOTIFS. ClassNotFoundException/NotSerializableException/UnmarshalException,
then we must emit a JMXConnectionNotification.LOST_NOTIFS.
*/ */
private NotificationResult fetchOneNotif() { private NotificationResult fetchOneNotif() {
ClientNotifForwarder cnf = ClientNotifForwarder.this; ClientNotifForwarder cnf = ClientNotifForwarder.this;
...@@ -668,23 +667,20 @@ public abstract class ClientNotifForwarder { ...@@ -668,23 +667,20 @@ public abstract class ClientNotifForwarder {
try { try {
// 1 notif to skip possible missing class // 1 notif to skip possible missing class
result = cnf.fetchNotifs(startSequenceNumber, 1, 0L); result = cnf.fetchNotifs(startSequenceNumber, 1, 0L);
} catch (Exception e) { } catch (ClassNotFoundException | NotSerializableException | UnmarshalException e) {
if (e instanceof ClassNotFoundException logger.warning("NotifFetcher.fetchOneNotif",
|| e instanceof NotSerializableException) { "Failed to deserialize a notification: "+e.toString());
logger.warning("NotifFetcher.fetchOneNotif", if (logger.traceOn()) {
"Failed to deserialize a notification: "+e.toString()); logger.trace("NotifFetcher.fetchOneNotif",
if (logger.traceOn()) { "Failed to deserialize a notification.", e);
logger.trace("NotifFetcher.fetchOneNotif",
"Failed to deserialize a notification.", e);
}
notFoundCount++;
startSequenceNumber++;
} else {
if (!shouldStop())
logger.trace("NotifFetcher.fetchOneNotif", e);
return null;
} }
notFoundCount++;
startSequenceNumber++;
} catch (Exception e) {
if (!shouldStop())
logger.trace("NotifFetcher.fetchOneNotif", e);
return null;
} }
} }
...@@ -692,7 +688,7 @@ public abstract class ClientNotifForwarder { ...@@ -692,7 +688,7 @@ public abstract class ClientNotifForwarder {
final String msg = final String msg =
"Dropped " + notFoundCount + " notification" + "Dropped " + notFoundCount + " notification" +
(notFoundCount == 1 ? "" : "s") + (notFoundCount == 1 ? "" : "s") +
" because classes were missing locally"; " because classes were missing locally or incompatible";
lostNotifs(msg, notFoundCount); lostNotifs(msg, notFoundCount);
// Even if result.getEarliestSequenceNumber() is now greater than // Even if result.getEarliestSequenceNumber() is now greater than
// it was initially, meaning some notifs have been dropped // it was initially, meaning some notifs have been dropped
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册