import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import javax.management.MBeanServerConnection; import javax.management.Notification; import javax.management.NotificationListener; import javax.management.ObjectName; import javax.management.remote.JMXConnectionNotification; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; public class Client { public static void run(String url) throws Exception { final int notifEmittedCnt = 10; final CountDownLatch counter = new CountDownLatch(notifEmittedCnt); final Set<Long> seqSet = Collections.synchronizedSet(new HashSet<Long>()); final AtomicBoolean duplNotification = new AtomicBoolean(); JMXServiceURL serverUrl = new JMXServiceURL(url); ObjectName name = new ObjectName("test", "foo", "bar"); JMXConnector jmxConnector = JMXConnectorFactory.connect(serverUrl); System.out.println("client connected"); jmxConnector.addConnectionNotificationListener(new NotificationListener() { @Override public void handleNotification(Notification notification, Object handback) { System.out.println("connection notification: " + notification); if (!seqSet.add(notification.getSequenceNumber())) { duplNotification.set(true); } if (notification.getType().equals(JMXConnectionNotification.NOTIFS_LOST)) { long lostNotifs = ((Long)((JMXConnectionNotification)notification).getUserData()).longValue(); for(int i=0;i<lostNotifs;i++) { counter.countDown(); } } } }, null, null); MBeanServerConnection jmxServer = jmxConnector.getMBeanServerConnection(); jmxServer.addNotificationListener(name, new NotificationListener() { @Override public void handleNotification(Notification notification, Object handback) { System.out.println("client got: " + notification); if (!seqSet.add(notification.getSequenceNumber())) { duplNotification.set(true); } counter.countDown(); } }, null, null); System.out.println("client invoking foo (" + notifEmittedCnt + " times)"); for(int i=0;i<notifEmittedCnt;i++) { System.out.print("."); jmxServer.invoke(name, "foo", new Object[]{}, new String[]{}); } System.out.println(); try { System.out.println("waiting for " + notifEmittedCnt + " notifications to arrive"); if (!counter.await(30, TimeUnit.SECONDS)) { throw new InterruptedException(); } if (duplNotification.get()) { System.out.println("ERROR: received duplicated notifications"); throw new Error("received duplicated notifications"); } System.out.println("\nshutting down client"); } catch (InterruptedException e) { System.out.println("ERROR: notification processing thread interrupted"); throw new Error("notification thread interrupted unexpectedly"); } } }