1 /* 2 * Copyright (c) 2006, 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 * @summary Test that we can create proxies which are NotificationEmitters. 27 * @bug 6411747 28 * @author Daniel Fuchs 29 * 30 * @run clean NotificationEmitterProxy 31 * @run build NotificationEmitterProxy 32 * @run main NotificationEmitterProxy 33 */ 34 35 import java.lang.management.ManagementFactory; 36 37 import javax.management.*; 38 import javax.management.remote.*; 39 import javax.naming.NoPermissionException; 40 41 public class NotificationEmitterProxy { 42 getInts()43 public static class Counter { 44 int count; 45 public synchronized int count() { 46 count++; 47 notifyAll(); 48 return count; 49 } 50 public synchronized int peek() { 51 return count; 52 } 53 public synchronized int waitfor(int max, long timeout) 54 throws InterruptedException { 55 final long start = System.currentTimeMillis(); 56 while (count < max && timeout > 0) { 57 final long rest = timeout - 58 (System.currentTimeMillis() - start); 59 if (rest <= 0) break; 60 wait(rest); 61 } 62 return count; 63 } 64 } isInt()65 66 public static class CounterListener 67 implements NotificationListener { 68 final private Counter counter; 69 public CounterListener(Counter counter) { 70 this.counter = counter; 71 } 72 public void handleNotification(Notification notification, 73 Object handback) { 74 System.out.println("Received notif from " + handback + 75 ":\n\t" + notification); 76 counter.count(); 77 } 78 } setInt(int a)79 80 public static void main(String[] args) throws Exception { 81 System.out.println("<<< Register for notification from a proxy"); 82 83 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 84 final ObjectName name = new ObjectName(":class=Simple"); 85 86 JMXServiceURL url = new JMXServiceURL("rmi", null, 0); 87 final JMXConnectorServer server = 88 JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); 89 server.start(); 90 url = server.getAddress(); 91 92 final JMXConnector client = JMXConnectorFactory.connect(url); 93 94 final Counter counter = new Counter(); 95 final CounterListener listener = new CounterListener(counter); 96 final Counter mxcounter = new Counter(); 97 final CounterListener mxlistener = new CounterListener(mxcounter); 98 final NotificationFilterSupport filter = 99 new NotificationFilterSupport(); 100 filter.enableType(MBeanServerNotification.REGISTRATION_NOTIFICATION); 101 filter.enableType(MBeanServerNotification.UNREGISTRATION_NOTIFICATION); 102 int registered = 0; 103 try { 104 final MBeanServerDelegateMBean delegate = 105 JMX.newMBeanProxy(client.getMBeanServerConnection(), 106 MBeanServerDelegate.DELEGATE_NAME, 107 MBeanServerDelegateMBean.class, 108 true); 109 110 NotificationEmitter emitter = (NotificationEmitter)delegate; 111 emitter.addNotificationListener(listener,filter,"JMX.newMBeanProxy"); 112 } catch (Exception x) { 113 throw new RuntimeException("Failed to register listener with "+ 114 " JMX.newMBeanProxy: " + x, x); 115 } 116 117 try { 118 final MBeanServerDelegateMBean delegate = 119 MBeanServerInvocationHandler.newProxyInstance(mbs, 120 MBeanServerDelegate.DELEGATE_NAME, 121 MBeanServerDelegateMBean.class, 122 true); 123 124 NotificationEmitter emitter = (NotificationEmitter)delegate; 125 emitter.addNotificationListener(listener,filter, 126 "MBeanServerInvocationHandler.newProxyInstance"); 127 } catch (Exception x) { 128 throw new RuntimeException("Failed to register listener with "+ 129 " MBeanServerInvocationHandler.newProxyInstance: " + x, x); 130 } 131 132 System.out.println("<<< Register an MBean."); 133 134 final Simple simple = new Simple(); 135 mbs.registerMBean(simple, name); 136 registered++; 137 138 SimpleMXBean simple0 = 139 JMX.newMXBeanProxy(client.getMBeanServerConnection(), 140 name, 141 SimpleMXBean.class, 142 true); 143 144 SimpleMXBean simple1 = 145 JMX.newMXBeanProxy(mbs, 146 name, 147 SimpleMXBean.class, 148 false); 149 150 final int expected = 2*registered; 151 final int reg = counter.waitfor(expected,3000); 152 if (reg != expected) 153 throw new RuntimeException("Bad notification count: " + reg + 154 ", expected " +expected); 155 System.out.println("Received expected "+reg+ 156 " notifs after registerMBean"); 157 158 ((NotificationEmitter)simple0) 159 .addNotificationListener(mxlistener,null,name); 160 simple1.equals("Are you a Wombat?"); 161 final int mxnotifs = mxcounter.waitfor(1,3000); 162 if (mxnotifs != 1) 163 throw new RuntimeException("Bad MXBean notification count: " + 164 mxnotifs); 165 System.out.println("Received expected "+mxnotifs+ 166 " notifs from MXBean"); 167 168 mbs.unregisterMBean(name); 169 final int unreg = counter.waitfor(expected+reg,3000); 170 if (unreg != (expected+reg)) 171 throw new RuntimeException("Bad notification count: " + unreg + 172 ", expected " +expected+reg); 173 System.out.println("Received expected "+(unreg-reg)+ 174 " notifs after unregisterMBean"); 175 System.out.println("Total notifs received: " + unreg); 176 177 178 } 179 180 public static interface Simplest { 181 182 } 183 184 public static interface SimpleMXBean extends Simplest { 185 public String equals(String x); 186 } 187 188 private static class Simple extends NotificationBroadcasterSupport 189 implements SimpleMXBean { 190 public static final String NOTIF_TYPE = "simple.equals"; 191 private static long seq=0; 192 private static synchronized long seq() { return ++seq; }; 193 public String equals(String x) { 194 sendNotification(new Notification(NOTIF_TYPE,this,seq(),x)); 195 return x; 196 } 197 198 } 199 200 201 202 } 203