--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/remote/mandatory/notif/UnexpectedNotifTest.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2003 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 7654321
+ * @summary Tests whether a listener receives notifs emitted before the
+ * listener is registered.
+ * @author Shanliang JIANG
+ * @run clean UnexpectedNotifTest
+ * @run build UnexpectedNotifTest
+ * @run main UnexpectedNotifTest
+ */
+
+// java imports
+//
+import java.io.IOException;
+
+// JMX imports
+//
+import javax.management.*;
+import javax.management.remote.*;
+
+public class UnexpectedNotifTest {
+
+ public static void main(String[] args) throws Exception {
+ String[] protos = null;
+ try {
+ Class.forName("javax.management.remote.jmxmp.JMXMPConnectorServer");
+ protos = new String[2];
+ protos[0] = "rmi";
+ protos[1] = "jmxmp";
+ } catch (ClassNotFoundException e) {
+ protos = new String[1];
+ protos[0] = "rmi";
+ }
+ for (int i = 0; i < protos.length; i++) {
+ System.out.println("Unexpected notifications test for protocol " +
+ protos[i]);
+ MBeanServer mbs = null;
+ try {
+ // Create a MBeanServer
+ //
+ mbs = MBeanServerFactory.createMBeanServer();
+
+ // Create a NotificationEmitter MBean
+ //
+ mbean = new ObjectName ("Default:name=NotificationEmitter");
+ mbs.registerMBean(new NotificationEmitter(), mbean);
+
+ // Create a connector server
+ //
+ url = new JMXServiceURL("service:jmx:" + protos[i] + "://");
+ server = JMXConnectorServerFactory.newJMXConnectorServer(url,
+ null,
+ mbs);
+
+ mbs.registerMBean(
+ server,
+ new ObjectName("Default:name=ConnectorServer"));
+
+ server.start();
+
+ url = server.getAddress();
+
+ for (int j = 0; j < 2; j++) {
+ test();
+ }
+ } finally {
+ // Stop server
+ //
+ server.stop();
+ // Release the MBeanServer
+ //
+ MBeanServerFactory.releaseMBeanServer(mbs);
+ }
+ }
+ }
+
+ private static void test() throws Exception {
+ // Create client
+ //
+ JMXConnector connector = JMXConnectorFactory.connect(url);
+ MBeanServerConnection client = connector.getMBeanServerConnection();
+
+ // Add listener at the client side
+ //
+ client.addNotificationListener(mbean, listener, null, null);
+
+ // Cleanup
+ //
+ receivedNotifs = 0;
+
+ // Ask to send notifs
+ //
+ Object[] params = new Object[] {new Integer(nb)};
+ String[] signatures = new String[] {"java.lang.Integer"};
+
+ client.invoke(mbean, "sendNotifications", params, signatures);
+
+ // Waiting...
+ //
+ synchronized (lock) {
+ for (int i = 0; i < 10; i++) {
+ if (receivedNotifs < nb) {
+ lock.wait(1000);
+ }
+ }
+ }
+
+ // Waiting again to ensure no more notifs
+ //
+ Thread.sleep(3000);
+
+ synchronized (lock) {
+ if (receivedNotifs != nb) {
+ throw new Exception("The client expected to receive " +
+ nb + " notifs, but got " + receivedNotifs);
+ }
+ }
+
+ // Remove listener
+ //
+ client.removeNotificationListener(mbean, listener);
+
+ connector.close();
+ }
+
+ //--------------------------
+ // private classes
+ //--------------------------
+
+ private static class Listener implements NotificationListener {
+ public void handleNotification(Notification notif, Object handback) {
+ System.out.println("Received: " + notif + " (" +
+ notif.getSequenceNumber() + ")");
+ synchronized(lock) {
+ if(++receivedNotifs == nb) {
+ lock.notifyAll();
+ } else if (receivedNotifs > nb) {
+ System.out.println("The client expected to receive " +
+ nb + " notifs, but got at least " +
+ receivedNotifs);
+ System.exit(1);
+ }
+ }
+ }
+ }
+
+ public static class NotificationEmitter
+ extends NotificationBroadcasterSupport
+ implements NotificationEmitterMBean {
+
+ /**
+ * Returns a NotificationInfo object containing the name of the Java
+ * class of the notification and the notification types sent by this
+ * notification broadcaster.
+ */
+ public MBeanNotificationInfo[] getNotificationInfo() {
+
+ MBeanNotificationInfo[] ntfInfoArray = new MBeanNotificationInfo[1];
+
+ String[] ntfTypes = new String[1];
+ ntfTypes[0] = myType;
+
+ ntfInfoArray[0] = new MBeanNotificationInfo(
+ ntfTypes,
+ "javax.management.Notification",
+ "Notifications sent by the NotificationEmitter");
+ return ntfInfoArray;
+ }
+
+ /**
+ * Send a Notification object with the specified times.
+ * The sequence number will be from zero to times-1.
+ *
+ * @param nb The number of notifications to send
+ */
+ public void sendNotifications(Integer nb) {
+ System.out.println("NotificationEmitter: asked to send " +
+ "notifications: " + nb);
+
+ Notification notif;
+ for (int i = 1; i <= nb.intValue(); i++) {
+ notif = new Notification(myType, this, ++seqno);
+ sendNotification(notif);
+ }
+ }
+
+ private String myType = "notification.my_notification";
+ }
+
+ public interface NotificationEmitterMBean {
+ public void sendNotifications(Integer nb);
+ }
+
+ private static JMXConnectorServer server;
+ private static JMXServiceURL url;
+ private static ObjectName mbean;
+ private static NotificationListener listener = new Listener();
+
+ private static int nb = 10;
+ private static int receivedNotifs = 0;
+ private static int[] lock = new int[0];
+ private static volatile long seqno;
+}