35
36 import java.security.AccessControlContext;
37 import java.security.AccessController;
38 import java.security.PrivilegedAction;
39 import javax.security.auth.Subject;
40
41 import javax.management.Notification;
42 import javax.management.NotificationListener;
43 import javax.management.NotificationFilter;
44 import javax.management.ObjectName;
45 import javax.management.MBeanServerNotification;
46 import javax.management.InstanceNotFoundException;
47 import javax.management.ListenerNotFoundException;
48
49 import javax.management.remote.NotificationResult;
50 import javax.management.remote.TargetedNotification;
51
52 import com.sun.jmx.remote.util.ClassLogger;
53 import com.sun.jmx.remote.util.EnvHelp;
54 import java.lang.reflect.UndeclaredThrowableException;
55 import java.rmi.UnmarshalException;
56 import java.util.concurrent.RejectedExecutionException;
57
58
59 public abstract class ClientNotifForwarder {
60
61 private final AccessControlContext acc;
62
63 public ClientNotifForwarder(Map<String, ?> env) {
64 this(null, env);
65 }
66
67 private static int threadId;
68
69 /* An Executor that allows at most one executing and one pending
70 Runnable. It uses at most one thread -- as soon as there is
71 no pending Runnable the thread can exit. Another thread is
72 created as soon as there is a new pending Runnable. This
73 Executor is adapted for use in a situation where each Runnable
74 usually schedules up another Runnable. On return from the
75 first one, the second one is immediately executed. So this
616 final String msg =
617 "Failed to forward a notification " +
618 "to a listener";
619 logger.trace("NotifFetcher-run", msg, e);
620 }
621
622 }
623
624 private NotificationResult fetchNotifs() {
625 try {
626 NotificationResult nr = ClientNotifForwarder.this.
627 fetchNotifs(clientSequenceNumber,maxNotifications,
628 timeout);
629
630 if (logger.traceOn()) {
631 logger.trace("NotifFetcher-run",
632 "Got notifications from the server: "+nr);
633 }
634
635 return nr;
636 } catch (ClassNotFoundException | NotSerializableException | UnmarshalException e) {
637 logger.trace("NotifFetcher.fetchNotifs", e);
638 return fetchOneNotif();
639 } catch (IOException ioe) {
640 if (!shouldStop()) {
641 logger.error("NotifFetcher-run",
642 "Failed to fetch notification, " +
643 "stopping thread. Error is: " + ioe, ioe);
644 logger.debug("NotifFetcher-run",ioe);
645 }
646
647 // no more fetching
648 return null;
649 }
650 }
651
652 /* Fetch one notification when we suspect that it might be a
653 notification that we can't deserialize (because of a
654 missing class). First we ask for 0 notifications with 0
655 timeout. This allows us to skip sequence numbers for
656 notifications that don't match our filters. Then we ask
688 logger.warning("NotifFetcher.fetchOneNotif",
689 "Impossible exception: " + e);
690 logger.debug("NotifFetcher.fetchOneNotif",e);
691 return null;
692 } catch (IOException e) {
693 if (!shouldStop())
694 logger.trace("NotifFetcher.fetchOneNotif", e);
695 return null;
696 }
697
698 if (shouldStop() || nr == null)
699 return null;
700
701 startSequenceNumber = nr.getNextSequenceNumber();
702 if (firstEarliest < 0)
703 firstEarliest = nr.getEarliestSequenceNumber();
704
705 try {
706 // 1 notif to skip possible missing class
707 result = cnf.fetchNotifs(startSequenceNumber, 1, 0L);
708 } catch (ClassNotFoundException | NotSerializableException | UnmarshalException e) {
709 logger.warning("NotifFetcher.fetchOneNotif",
710 "Failed to deserialize a notification: "+e.toString());
711 if (logger.traceOn()) {
712 logger.trace("NotifFetcher.fetchOneNotif",
713 "Failed to deserialize a notification.", e);
714 }
715
716 notFoundCount++;
717 startSequenceNumber++;
718 } catch (Exception e) {
719 if (!shouldStop())
720 logger.trace("NotifFetcher.fetchOneNotif", e);
721 return null;
722 }
723 }
724
725 if (notFoundCount > 0) {
726 final String msg =
727 "Dropped " + notFoundCount + " notification" +
728 (notFoundCount == 1 ? "" : "s") +
|
35
36 import java.security.AccessControlContext;
37 import java.security.AccessController;
38 import java.security.PrivilegedAction;
39 import javax.security.auth.Subject;
40
41 import javax.management.Notification;
42 import javax.management.NotificationListener;
43 import javax.management.NotificationFilter;
44 import javax.management.ObjectName;
45 import javax.management.MBeanServerNotification;
46 import javax.management.InstanceNotFoundException;
47 import javax.management.ListenerNotFoundException;
48
49 import javax.management.remote.NotificationResult;
50 import javax.management.remote.TargetedNotification;
51
52 import com.sun.jmx.remote.util.ClassLogger;
53 import com.sun.jmx.remote.util.EnvHelp;
54 import java.lang.reflect.UndeclaredThrowableException;
55 import java.util.concurrent.RejectedExecutionException;
56
57
58 public abstract class ClientNotifForwarder {
59
60 private final AccessControlContext acc;
61
62 public ClientNotifForwarder(Map<String, ?> env) {
63 this(null, env);
64 }
65
66 private static int threadId;
67
68 /* An Executor that allows at most one executing and one pending
69 Runnable. It uses at most one thread -- as soon as there is
70 no pending Runnable the thread can exit. Another thread is
71 created as soon as there is a new pending Runnable. This
72 Executor is adapted for use in a situation where each Runnable
73 usually schedules up another Runnable. On return from the
74 first one, the second one is immediately executed. So this
615 final String msg =
616 "Failed to forward a notification " +
617 "to a listener";
618 logger.trace("NotifFetcher-run", msg, e);
619 }
620
621 }
622
623 private NotificationResult fetchNotifs() {
624 try {
625 NotificationResult nr = ClientNotifForwarder.this.
626 fetchNotifs(clientSequenceNumber,maxNotifications,
627 timeout);
628
629 if (logger.traceOn()) {
630 logger.trace("NotifFetcher-run",
631 "Got notifications from the server: "+nr);
632 }
633
634 return nr;
635 } catch (ClassNotFoundException | NotSerializableException e) {
636 logger.trace("NotifFetcher.fetchNotifs", e);
637 return fetchOneNotif();
638 } catch (IOException ioe) {
639 if (!shouldStop()) {
640 logger.error("NotifFetcher-run",
641 "Failed to fetch notification, " +
642 "stopping thread. Error is: " + ioe, ioe);
643 logger.debug("NotifFetcher-run",ioe);
644 }
645
646 // no more fetching
647 return null;
648 }
649 }
650
651 /* Fetch one notification when we suspect that it might be a
652 notification that we can't deserialize (because of a
653 missing class). First we ask for 0 notifications with 0
654 timeout. This allows us to skip sequence numbers for
655 notifications that don't match our filters. Then we ask
687 logger.warning("NotifFetcher.fetchOneNotif",
688 "Impossible exception: " + e);
689 logger.debug("NotifFetcher.fetchOneNotif",e);
690 return null;
691 } catch (IOException e) {
692 if (!shouldStop())
693 logger.trace("NotifFetcher.fetchOneNotif", e);
694 return null;
695 }
696
697 if (shouldStop() || nr == null)
698 return null;
699
700 startSequenceNumber = nr.getNextSequenceNumber();
701 if (firstEarliest < 0)
702 firstEarliest = nr.getEarliestSequenceNumber();
703
704 try {
705 // 1 notif to skip possible missing class
706 result = cnf.fetchNotifs(startSequenceNumber, 1, 0L);
707 } catch (ClassNotFoundException | NotSerializableException e) {
708 logger.warning("NotifFetcher.fetchOneNotif",
709 "Failed to deserialize a notification: "+e.toString());
710 if (logger.traceOn()) {
711 logger.trace("NotifFetcher.fetchOneNotif",
712 "Failed to deserialize a notification.", e);
713 }
714
715 notFoundCount++;
716 startSequenceNumber++;
717 } catch (Exception e) {
718 if (!shouldStop())
719 logger.trace("NotifFetcher.fetchOneNotif", e);
720 return null;
721 }
722 }
723
724 if (notFoundCount > 0) {
725 final String msg =
726 "Dropped " + notFoundCount + " notification" +
727 (notFoundCount == 1 ? "" : "s") +
|