1 /* 2 * Copyright (c) 2003, 2015, 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 * @modules java.management 30 * @run clean DiffHBTest 31 * @run build DiffHBTest 32 * @run main DiffHBTest 33 */ 34 35 36 import javax.management.*; 37 import javax.management.remote.*; 38 39 /** 40 * This test registeres an unique listener with two different handbacks, 41 * it expects to receive a same notification two times. 42 */ 43 public class DiffHBTest { 44 private static final String[] protocols = {"rmi", "iiop", "jmxmp"}; 45 46 private static final MBeanServer mbs = MBeanServerFactory.createMBeanServer(); 47 private static ObjectName delegateName; 48 private static ObjectName timerName; 49 50 public static final String[] hbs = new String[] {"0", "1"}; 51 52 public static void main(String[] args) throws Exception { 53 System.out.println(">>> test on one listener with two different handbacks."); 54 55 delegateName = new ObjectName("JMImplementation:type=MBeanServerDelegate"); 56 timerName = new ObjectName("MBean:name=Timer"); 57 58 String errors = ""; 59 60 for (int i = 0; i < protocols.length; i++) { 61 final String s = test(protocols[i]); 62 if (s != null) { 63 if ("".equals(errors)) { 64 errors = "Failed to " + protocols[i] + ": "+s; 65 } else { 66 errors = "\tFailed to " + protocols[i] + ": "+s; 67 } 68 } 69 } 70 71 if ("".equals(errors)) { 72 System.out.println(">>> Passed!"); 73 } else { 74 System.out.println(">>> Failed!"); 75 76 throw new RuntimeException(errors); 77 } 78 } 79 80 private static String test(String proto) throws Exception { 81 System.out.println(">>> Test for protocol " + proto); 82 JMXServiceURL u = new JMXServiceURL(proto, null, 0); 83 JMXConnectorServer server; 84 JMXConnector client; 85 86 try { 87 server = 88 JMXConnectorServerFactory.newJMXConnectorServer(u, null, mbs); 89 server.start(); 90 JMXServiceURL addr = server.getAddress(); 91 client = JMXConnectorFactory.connect(addr, null); 92 } catch (Exception e) { 93 // not support 94 System.out.println(">>> not support: " + proto); 95 return null; 96 } 97 98 MBeanServerConnection mserver = client.getMBeanServerConnection(); 99 100 System.out.print(">>>\t"); 101 for (int i=0; i<5; i++) { 102 System.out.print(i + "\t"); 103 final MyListener dummyListener = new MyListener(); 104 mserver.addNotificationListener( 105 delegateName, dummyListener, null, hbs[0]); 106 mserver.addNotificationListener( 107 delegateName, dummyListener, null, hbs[1]); 108 109 mserver.createMBean("javax.management.timer.Timer", timerName); 110 111 long remainingTime = waitingTime; 112 final long startTime = System.currentTimeMillis(); 113 114 try { 115 synchronized(dummyListener) { 116 while (!dummyListener.done && remainingTime > 0) { 117 dummyListener.wait(remainingTime); 118 remainingTime = waitingTime - 119 (System.currentTimeMillis() - startTime); 120 } 121 122 if (dummyListener.errorInfo != null) { 123 return dummyListener.errorInfo; 124 } 125 } 126 } finally { 127 //System.out.println("Unregister: "+i); 128 mserver.unregisterMBean(timerName); 129 mserver.removeNotificationListener(delegateName, dummyListener); 130 } 131 } 132 133 System.out.println(""); 134 client.close(); 135 server.stop(); 136 137 return null; 138 } 139 140 private static class MyListener implements NotificationListener { 141 public boolean done = false; 142 public String errorInfo = null; 143 144 private int received = 0; 145 private MBeanServerNotification receivedNotif = null; 146 private Object receivedHB = null; 147 public void handleNotification(Notification n, Object o) { 148 if (!(n instanceof MBeanServerNotification)) { 149 failed("Received an unexpected notification: "+n); 150 return; 151 } 152 153 if (!hbs[0].equals(o) && !hbs[1].equals(o)) { 154 failed("Unkown handback: "+o); 155 return; 156 } 157 158 // what we need 159 final MBeanServerNotification msn = (MBeanServerNotification)n; 160 if (!(MBeanServerNotification.REGISTRATION_NOTIFICATION.equals( 161 msn.getType())) || 162 !msn.getMBeanName().equals(timerName)) { 163 return; 164 } 165 166 synchronized(this) { 167 received++; 168 169 if (received == 1) { // first time 170 receivedNotif = msn; 171 receivedHB = o; 172 173 return; 174 } 175 176 if (received > 2) { 177 failed("Expect to receive 2 notifs, but get "+received); 178 179 return; 180 } 181 182 // second time 183 if (receivedHB.equals(o)) { 184 failed("Got same handback twice: "+o); 185 } else if(!hbs[0].equals(o) && !hbs[1].equals(o)) { 186 failed("Unknown handback: "+o); 187 } else if (receivedNotif.getSequenceNumber() != 188 msn.getSequenceNumber()) { 189 failed("expected to receive:\n" 190 +receivedNotif 191 +"\n but got\n"+msn); 192 } 193 194 // passed 195 done = true; 196 this.notify(); 197 } 198 } 199 200 private void failed(String errorInfo) { 201 this.errorInfo = errorInfo; 202 done = true; 203 204 this.notify(); 205 } 206 } 207 208 private final static long waitingTime = 2000; 209 }