1 /* 2 * Copyright (c) 2003, 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 4874819 27 * @summary Test that MBeanInfo classes no longer throw an 28 * IllegalArgumentException when attribute names, operation names, and 29 * Java type names do not strictly follow the expected Java syntax. 30 * @author Eamonn McManus, Daniel Fuchs 31 * @run clean SimpleModelMBeanCommand 32 * @run build SimpleModelMBeanCommand 33 * @run main/othervm/policy=policy SimpleModelMBeanCommand 34 */ 35 36 import java.lang.reflect.*; 37 import java.util.*; 38 import javax.management.*; 39 import javax.management.modelmbean.*; 40 41 public class SimpleModelMBeanCommand { 42 43 public static class Resource { 44 public int getNumber() { 45 return number; 46 } 47 48 public void setNumber(int n) { 49 number = n; 50 } 51 52 public int addOne(int x) { 53 return x + 1; 54 } 55 56 public Object[] getArray() { 57 return (Object[]) array.clone(); 58 } 59 60 // doesn't look like an attribute so not seen by caching logic 61 public void tweakArray(Object[] array) { 62 this.array = (Object[]) array.clone(); 63 } 64 65 private int number = 1234; 66 private Object[] array = {"hello", "world"}; 67 } 68 69 public static void main(String[] args) { 70 int errorCount = 0; 71 for (int i = 0; i < NTESTS; i++) { 72 try { 73 System.out.println("Test " + i + ":"); 74 test(i); 75 } catch (Throwable e) { 76 errorCount++; 77 boolean first = true; 78 do { 79 System.err.println(first ? "Exception:" : "Caused by:"); 80 first = false; 81 e.printStackTrace(); 82 Throwable nexte; 83 nexte = e.getCause(); 84 if (nexte == null) { // old JMX 85 if (e instanceof MBeanException) 86 nexte = ((MBeanException) e).getTargetException(); 87 } 88 e = nexte; 89 } while (e != null); 90 } 91 } 92 if (errorCount == 0) { 93 System.out.println("All ModelMBean tests successfuly passed"); 94 System.out.println("Bye! Bye!"); 95 // JTReg doesn't like System.exit(0); 96 return; 97 } else { 98 System.err.println("ERROR: " + errorCount + " tests failed"); 99 System.exit(errorCount); 100 } 101 102 } 103 104 private static void test(int testno) throws Exception { 105 // com.sun.jmx.trace.TraceImplementation.init(2); 106 Resource resource = new Resource(); 107 Class resourceClass = Resource.class; 108 Class rmmbClass = RequiredModelMBean.class; 109 Method setManagedResource = 110 rmmbClass.getMethod("setManagedResource", 111 new Class[] {Object.class, 112 String.class}); 113 Method sendNotification = 114 rmmbClass.getMethod("sendNotification", 115 new Class[] {Notification.class}); 116 Method addAttributeChangeNL = 117 rmmbClass.getMethod("addAttributeChangeNotificationListener", 118 new Class[] {NotificationListener.class, 119 String.class, 120 Object.class}); 121 Method getArray = resourceClass.getMethod("getArray", new Class[0]); 122 Method getNumber = resourceClass.getMethod("getNumber", new Class[0]); 123 Method setNumber = 124 resourceClass.getMethod("setNumber", new Class[] {Integer.TYPE}); 125 Method tweakArray = 126 resourceClass.getMethod("tweakArray", 127 new Class[] {Object[].class}); 128 Method addOne = 129 resourceClass.getMethod("addOne", new Class[] {Integer.TYPE}); 130 MBeanServer mbs = MBeanServerFactory.newMBeanServer(); 131 ObjectName on = new ObjectName("a:b=c"); 132 Descriptor attrDescr = new DescriptorSupport(); 133 attrDescr.setField("name", "Array"); 134 attrDescr.setField("descriptorType", "attribute"); 135 attrDescr.setField("getMethod", "getArray"); 136 ModelMBeanAttributeInfo attrInfo = 137 new ModelMBeanAttributeInfo("Array", "array attr", getArray, 138 null, attrDescr); 139 Descriptor attrDescr2 = new DescriptorSupport(); 140 attrDescr2.setField("name", "Number"); 141 attrDescr2.setField("descriptorType", "attribute"); 142 attrDescr2.setField("getMethod", "getNumber"); 143 attrDescr2.setField("setMethod", "setNumber"); 144 ModelMBeanAttributeInfo attrInfo2 = 145 new ModelMBeanAttributeInfo("Number", "number attr", getNumber, 146 setNumber, attrDescr2); 147 Descriptor attrDescr3 = new DescriptorSupport(); 148 attrDescr3.setField("name", "Local"); 149 attrDescr3.setField("descriptorType", "attribute"); 150 attrDescr3.setField("currencyTimeLimit", "" + Integer.MAX_VALUE); 151 ModelMBeanAttributeInfo attrInfo3 = 152 new ModelMBeanAttributeInfo("Local", "java.lang.String", 153 "local attr", true, true, false, 154 attrDescr3); 155 Descriptor attrDescr4 = new DescriptorSupport(); 156 attrDescr4.setField("name", "Local2"); 157 attrDescr4.setField("descriptorType", "attribute"); 158 ModelMBeanAttributeInfo attrInfo4 = 159 new ModelMBeanAttributeInfo("Local2", "java.lang.String", 160 "local attr 2", true, true, false, 161 attrDescr4); 162 ModelMBeanAttributeInfo[] attrs = 163 new ModelMBeanAttributeInfo[] {attrInfo, attrInfo2, attrInfo3, 164 attrInfo4}; 165 ModelMBeanOperationInfo operInfo = 166 new ModelMBeanOperationInfo("getArray descr", getArray); 167 ModelMBeanOperationInfo operInfo2 = 168 new ModelMBeanOperationInfo("getNumber descr", getNumber); 169 ModelMBeanOperationInfo operInfo3 = 170 new ModelMBeanOperationInfo("addOne descr", addOne); 171 ModelMBeanOperationInfo operInfo4 = 172 new ModelMBeanOperationInfo("setNumber descr", setNumber); 173 ModelMBeanOperationInfo operInfo5 = 174 new ModelMBeanOperationInfo("tweakArray descr", tweakArray); 175 ModelMBeanOperationInfo operInfoSetManagedResource = 176 new ModelMBeanOperationInfo("setManagedResource descr", 177 setManagedResource); 178 ModelMBeanOperationInfo operInfoSendNotification = 179 new ModelMBeanOperationInfo("sendNotification descr", 180 sendNotification); 181 ModelMBeanOperationInfo operInfoAddAttributeChangeNL = 182 new ModelMBeanOperationInfo("AddAttributeChangeNL descr", 183 addAttributeChangeNL); 184 ModelMBeanOperationInfo[] opers = 185 new ModelMBeanOperationInfo[] {operInfo, operInfo2, operInfo3, 186 operInfo4, operInfo5, 187 operInfoSetManagedResource, 188 operInfoSendNotification, 189 operInfoAddAttributeChangeNL}; 190 ModelMBeanInfo info = 191 new ModelMBeanInfoSupport(Resource.class.getName(), 192 "Resourcish resource", 193 attrs, null, opers, null, 194 null); 195 mbs.createMBean(RequiredModelMBean.class.getName(), 196 on, 197 new Object[] {info}, 198 new String[] {ModelMBeanInfo.class.getName()}); 199 mbs.invoke(on, "setManagedResource", 200 new Object[] {resource, "objectReference"}, 201 new String[] {"java.lang.Object", "java.lang.String"}); 202 switch (testno) { 203 case 0: 204 /* Check that we can get an attribute of type Object[] */ 205 Object[] objs = (Object[]) mbs.getAttribute(on, "Array"); 206 for (int i = 0; i < objs.length; i++) 207 System.out.println(objs[i]); 208 break; 209 case 1: 210 /* Check that we can get an attribute of type int */ 211 Integer n = (Integer) mbs.getAttribute(on, "Number"); 212 System.out.println(n); 213 break; 214 case 2: 215 /* Check that we can call an operation that returns int */ 216 Integer n1 = 217 (Integer) mbs.invoke(on, "addOne", 218 new Integer[] {new Integer(1233)}, 219 new String[] {"int"}); 220 System.out.println(n1); 221 break; 222 case 3: 223 /* Check that we don't get an exception if you sendNotification 224 without any listeners. */ 225 Notification notif = new Notification("type", "source", 123L); 226 mbs.invoke(on, "sendNotification", new Object[] {notif}, 227 new String[] {"javax.management.Notification"}); 228 System.out.println("Successfully sent notification"); 229 break; 230 case 4: 231 /* Check that we can call addAttributeChangeNotificationListener 232 with null attribute. */ 233 NotificationListener listener = new NotificationListener() { 234 public void handleNotification(Notification notif, 235 Object handback) { 236 System.out.println("Got notif: " + notif + 237 " with handback: " + handback); 238 } 239 }; 240 mbs.invoke(on, "addAttributeChangeNotificationListener", 241 new Object[] {listener, null, "the-handback"}, 242 new String[] { 243 "javax.management.NotificationListener", 244 "java.lang.String", 245 "java.lang.Object", 246 }); 247 mbs.setAttribute(on, new Attribute("Number", new Integer(4321))); 248 System.out.println("Attribute value now: " + 249 mbs.getAttribute(on, "Number")); 250 break; 251 case 5: 252 /* Check that the default caching behaviour is not to cache. */ 253 Object[] firstGot = (Object[]) mbs.getAttribute(on, "Array"); 254 System.out.println("First got: " + Arrays.asList(firstGot)); 255 ModelMBeanInfo mmbi = (ModelMBeanInfo) mbs.getMBeanInfo(on); 256 System.out.println(mmbi.getDescriptor("Array", "attribute")); 257 mbs.invoke(on, "tweakArray", new Object[] {new Object[] {"x"}}, 258 new String[] {Object[].class.getName()}); 259 Object[] secondGot = (Object[]) mbs.getAttribute(on, "Array"); 260 System.out.println("Second got: " + Arrays.asList(secondGot)); 261 if (secondGot.length != 1) 262 throw new Exception("Got value: " + Arrays.asList(secondGot)); 263 break; 264 case 6: 265 /* Check that attributes without getters or setters work. 266 The value is stored in the descriptor. This test includes 267 an explicit currencyTimeLimit attribute. */ 268 mbs.setAttribute(on, new Attribute("Local", "string value")); 269 ModelMBeanInfo mmbi2 = (ModelMBeanInfo) mbs.getMBeanInfo(on); 270 System.out.println(mmbi2.getDescriptor("Local", "attribute")); 271 Object gotback = mbs.getAttribute(on, "Local"); 272 if (!"string value".equals(gotback)) 273 throw new Exception("Got value: " + gotback); 274 break; 275 case 7: 276 /* Check that attributes without getters or setters work. 277 The value is stored in the descriptor. This test does 278 not have an explicit currencyTimeLimit attribute. */ 279 mbs.setAttribute(on, new Attribute("Local2", "thing value")); 280 ModelMBeanInfo mmbi3 = (ModelMBeanInfo) mbs.getMBeanInfo(on); 281 System.out.println(mmbi3.getDescriptor("Local2", "attribute")); 282 Object gotback2 = mbs.getAttribute(on, "Local2"); 283 if (!"thing value".equals(gotback2)) 284 throw new Exception("Got value: " + gotback2); 285 break; 286 default: 287 System.err.println("UNKNOWN TEST NUMBER " + testno); 288 break; 289 } 290 } 291 292 private static final int NTESTS = 8; 293 294 }