1 /* 2 * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4911721 27 * @summary test on add/remove NotificationListener 28 * @author Shanliang JIANG 29 * @run clean DiffHBTest 30 * @run build DiffHBTest 31 * @run main DiffHBTest 32 */ 33 34 35 import javax.management.*; 36 import javax.management.remote.*; 37 38 /** 39 * This test registeres an unique listener with two different handbacks, 40 * it expects to receive a same notification two times. 41 */ 42 public class DiffHBTest { 43 private static final String[] protocols = {"rmi", "iiop", "jmxmp"}; 44 45 private static final MBeanServer mbs = MBeanServerFactory.createMBeanServer(); 46 private static ObjectName delegateName; 47 private static ObjectName timerName; 48 49 public static final String[] hbs = new String[] {"0", "1"}; 50 51 public static void main(String[] args) throws Exception { 52 System.out.println(">>> test on one listener with two different handbacks."); 53 54 delegateName = new ObjectName("JMImplementation:type=MBeanServerDelegate"); 55 timerName = new ObjectName("MBean:name=Timer"); 56 57 String errors = ""; 58 59 for (int i = 0; i < protocols.length; i++) { 60 final String s = test(protocols[i]); 61 if (s != null) { 62 if ("".equals(errors)) { 63 errors = "Failed to " + protocols[i] + ": "+s; 64 } else { 65 errors = "\tFailed to " + protocols[i] + ": "+s; 66 } 67 } 68 } 69 70 if ("".equals(errors)) { 71 System.out.println(">>> Passed!"); 72 } else { 73 System.out.println(">>> Failed!"); 74 75 throw new RuntimeException(errors); 76 } 77 } 78 79 private static String test(String proto) throws Exception { 80 System.out.println(">>> Test for protocol " + proto); 81 JMXServiceURL u = new JMXServiceURL(proto, null, 0); 82 JMXConnectorServer server; 83 JMXConnector client; 84 85 try { 86 server = 87 JMXConnectorServerFactory.newJMXConnectorServer(u, null, mbs); 88 server.start(); 89 JMXServiceURL addr = server.getAddress(); 90 client = JMXConnectorFactory.connect(addr, null); 91 } catch (Exception e) { 92 // not support 93 System.out.println(">>> not support: " + proto); 94 return null; 95 } 96 97 MBeanServerConnection mserver = client.getMBeanServerConnection(); 98 99 System.out.print(">>>\t"); 100 for (int i=0; i<5; i++) { 101 System.out.print(i + "\t"); 102 final MyListener dummyListener = new MyListener(); 103 mserver.addNotificationListener( 104 delegateName, dummyListener, null, hbs[0]); 105 mserver.addNotificationListener( 106 delegateName, dummyListener, null, hbs[1]); 107 108 mserver.createMBean("javax.management.timer.Timer", timerName); 109 110 long remainingTime = waitingTime; 111 final long startTime = System.currentTimeMillis(); 112 113 try { 114 synchronized(dummyListener) { 115 while (!dummyListener.done && remainingTime > 0) { 116 dummyListener.wait(remainingTime); 117 remainingTime = waitingTime - 118 (System.currentTimeMillis() - startTime); 119 } 120 121 if (dummyListener.errorInfo != null) { 122 return dummyListener.errorInfo; 123 } 124 } 125 } finally { 126 //System.out.println("Unregister: "+i); 127 mserver.unregisterMBean(timerName); 128 mserver.removeNotificationListener(delegateName, dummyListener); 129 } 130 } 131 132 System.out.println(""); 133 client.close(); 134 server.stop(); 135 136 return null; 137 } 138 139 private static class MyListener implements NotificationListener { 140 public boolean done = false; 141 public String errorInfo = null; 142 143 private int received = 0; 144 private MBeanServerNotification receivedNotif = null; 145 private Object receivedHB = null; 146 public void handleNotification(Notification n, Object o) { 147 if (!(n instanceof MBeanServerNotification)) { 148 failed("Received an unexpected notification: "+n); 149 return; 150 } 151 152 if (!hbs[0].equals(o) && !hbs[1].equals(o)) { 153 failed("Unkown handback: "+o); 154 return; 155 } 156 157 // what we need 158 final MBeanServerNotification msn = (MBeanServerNotification)n; 159 if (!(MBeanServerNotification.REGISTRATION_NOTIFICATION.equals( 160 msn.getType())) || 161 !msn.getMBeanName().equals(timerName)) { 162 return; 163 } 164 165 synchronized(this) { 166 received++; 167 168 if (received == 1) { // first time 169 receivedNotif = msn; 170 receivedHB = o; 171 172 return; 173 } 174 175 if (received > 2) { 176 failed("Expect to receive 2 notifs, but get "+received); 177 178 return; 179 } 180 181 // second time 182 if (receivedHB.equals(o)) { 183 failed("Got same handback twice: "+o); 184 } else if(!hbs[0].equals(o) && !hbs[1].equals(o)) { 185 failed("Unknown handback: "+o); 186 } else if (receivedNotif.getSequenceNumber() != 187 msn.getSequenceNumber()) { 188 failed("expected to receive:\n" 189 +receivedNotif 190 +"\n but got\n"+msn); 191 } 192 193 // passed 194 done = true; 195 this.notify(); 196 } 197 } 198 199 private void failed(String errorInfo) { 200 this.errorInfo = errorInfo; 201 done = true; 202 203 this.notify(); 204 } 205 } 206 207 private final static long waitingTime = 2000; 208 }