diff -r fd16c54261b3 -r 90ce3da70b43 jdk/test/javax/management/remote/mandatory/notif/UnexpectedNotifTest.java --- /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; +}