1 /* 2 * Copyright (c) 2005, 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 8058865 27 * @summary Checks correct exception and error events from NotificationListener 28 * @author Olivier Lagneau 29 * @modules java.management.rmi 30 * @library /lib/testlibrary 31 * @compile Basic.java 32 * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanExceptionHandlingTest -timeForNotificationInSeconds 3 33 */ 34 35 36 import java.util.Map; 37 import java.util.HashMap; 38 import java.util.concurrent.ArrayBlockingQueue; 39 import java.util.concurrent.BlockingQueue; 40 41 import java.lang.management.ManagementFactory; 42 import javax.management.MBeanServer; 43 import javax.management.MBeanException; 44 import javax.management.MBeanServerDelegate; 45 import javax.management.Notification; 46 import javax.management.NotificationListener; 47 import javax.management.MBeanServerConnection; 48 import javax.management.ObjectName; 49 import javax.management.RuntimeErrorException; 50 import javax.management.remote.JMXConnector; 51 import javax.management.remote.JMXConnectorFactory; 52 import javax.management.remote.JMXConnectorServer; 53 import javax.management.remote.JMXConnectorServerFactory; 54 import javax.management.remote.JMXServiceURL; 55 56 public class MXBeanExceptionHandlingTest implements NotificationListener { 57 58 private static String BASIC_MXBEAN_CLASS_NAME = "Basic"; 59 60 private long timeForNotificationInSeconds = 3L; 61 private int numOfNotifications = 2; 62 private BlockingQueue<Notification> notifList = null; 63 64 65 /* 66 * First Debug properties and arguments are collect in expected 67 * map (argName, value) format, then calls original test's run method. 68 */ 69 public static void main(String args[]) throws Exception { 70 71 System.out.println("================================================="); 72 73 // Parses parameters 74 Utils.parseDebugProperties(); 75 Map<String, Object> map = Utils.parseParameters(args) ; 76 77 // Run test 78 MXBeanExceptionHandlingTest test = new MXBeanExceptionHandlingTest(); 79 test.run(map); 80 81 } 82 83 protected void parseArgs(Map<String, Object> args) throws Exception { 84 85 String arg = null; 86 87 // Init timeForNotificationInSeconds 88 // It is the maximum time in seconds we wait for a notification. 89 arg = (String)args.get("-timeForNotificationInSeconds") ; 90 if (arg != null) { 91 timeForNotificationInSeconds = (new Long(arg)).longValue(); 92 } 93 94 } 95 96 public void run(Map<String, Object> args) { 97 98 System.out.println("MXBeanExceptionHandlingTest::run: Start") ; 99 int errorCount = 0 ; 100 101 try { 102 parseArgs(args); 103 notifList = new ArrayBlockingQueue<Notification>(numOfNotifications); 104 105 // JMX MbeanServer used inside single VM as if remote. 106 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 107 108 JMXServiceURL url = new JMXServiceURL("rmi", null, 0); 109 JMXConnectorServer cs = 110 JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); 111 cs.start(); 112 113 JMXServiceURL addr = cs.getAddress(); 114 JMXConnector cc = JMXConnectorFactory.connect(addr); 115 MBeanServerConnection mbsc = cc.getMBeanServerConnection(); 116 117 // ---- 118 System.out.println("Add me as notification listener"); 119 mbsc.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME, 120 this, null, null); 121 System.out.println("---- OK\n") ; 122 123 // ---- 124 System.out.println("Create and register the MBean"); 125 ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ; 126 mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName); 127 System.out.println("---- OK\n") ; 128 129 // ---- 130 System.out.println("Call method throwException on our MXBean"); 131 132 try { 133 mbsc.invoke(objName, "throwException", null, null); 134 errorCount++; 135 System.out.println("(ERROR) Did not get awaited MBeanException") ; 136 } catch (MBeanException mbe) { 137 System.out.println("(OK) Got awaited MBeanException") ; 138 Throwable cause = mbe.getCause(); 139 140 if ( cause instanceof java.lang.Exception ) { 141 System.out.println("(OK) Cause is of the right class") ; 142 String mess = cause.getMessage(); 143 144 if ( mess.equals(Basic.EXCEPTION_MESSAGE ) ) { 145 System.out.println("(OK) Cause message is fine") ; 146 } else { 147 errorCount++; 148 System.out.println("(ERROR) Cause has message " 149 + cause.getMessage() 150 + " as we expect " 151 + Basic.EXCEPTION_MESSAGE) ; 152 } 153 } else { 154 errorCount++; 155 System.out.println("(ERROR) Cause is of class " 156 + cause.getClass().getName() 157 + " as we expect java.lang.Exception") ; 158 } 159 } catch (Exception e) { 160 errorCount++; 161 System.out.println("(ERROR) Did not get awaited MBeanException but " 162 + e) ; 163 Utils.printThrowable(e, true); 164 } 165 System.out.println("---- DONE\n") ; 166 167 // ---- 168 System.out.println("Call method throwError on our MXBean"); 169 170 try { 171 mbsc.invoke(objName, "throwError", null, null); 172 errorCount++; 173 System.out.println("(ERROR) Did not get awaited RuntimeErrorException") ; 174 } catch (RuntimeErrorException ree) { 175 System.out.println("(OK) Got awaited RuntimeErrorException") ; 176 Throwable cause = ree.getCause(); 177 178 if ( cause instanceof java.lang.InternalError ) { 179 System.out.println("(OK) Cause is of the right class") ; 180 String mess = cause.getMessage(); 181 182 if ( mess.equals(Basic.EXCEPTION_MESSAGE ) ) { 183 System.out.println("(OK) Cause message is fine") ; 184 } else { 185 errorCount++; 186 System.out.println("(ERROR) Cause has message " 187 + cause.getMessage() 188 + " as we expect " 189 + Basic.EXCEPTION_MESSAGE) ; 190 } 191 } else { 192 errorCount++; 193 System.out.println("(ERROR) Cause is of class " 194 + cause.getClass().getName() 195 + " as we expect java.lang.InternalError") ; 196 } 197 } catch (Exception e) { 198 errorCount++; 199 System.out.println("(ERROR) Did not get awaited RuntimeErrorException but " 200 + e) ; 201 Utils.printThrowable(e, true); 202 } 203 System.out.println("---- DONE\n") ; 204 205 // ---- 206 System.out.println("Unregister the MBean"); 207 mbsc.unregisterMBean(objName); 208 System.out.println("---- OK\n") ; 209 210 Thread.sleep(timeForNotificationInSeconds * 1000); 211 int numOfReceivedNotif = notifList.size(); 212 213 if ( numOfReceivedNotif == numOfNotifications ) { 214 System.out.println("(OK) We received " 215 + numOfNotifications 216 + " Notifications") ; 217 } else { 218 errorCount++; 219 System.out.println("(ERROR) We received " 220 + numOfReceivedNotif 221 + " Notifications in place of " 222 + numOfNotifications) ; 223 } 224 } catch(Exception e) { 225 Utils.printThrowable(e, true) ; 226 throw new RuntimeException(e); 227 } 228 229 if ( errorCount == 0 ) { 230 System.out.println("MXBeanExceptionHandlingTest::run: Done without any error") ; 231 } else { 232 System.out.println("MXBeanExceptionHandlingTest::run: Done with " 233 + errorCount 234 + " error(s)") ; 235 throw new RuntimeException("errorCount = " + errorCount); 236 } 237 } 238 239 public void handleNotification(Notification notification, Object handback) { 240 System.out.println("MXBeanExceptionHandlingTest::handleNotification: Received " 241 + notification); 242 notifList.add(notification); 243 } 244 245 }