1 /* 2 * Copyright (c) 2005, 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 6337061 27 * @summary Test that ModelMBeanInfoSupport.getDescriptors(null) also 28 * returns the MBean's descriptor. 29 * @author Eamonn McManus, Daniel Fuchs 30 * @run clean GetAllDescriptorsTest 31 * @run build GetAllDescriptorsTest 32 * @run main/othervm/policy=policy GetAllDescriptorsTest 33 */ 34 35 import java.lang.reflect.*; 36 import java.util.*; 37 import javax.management.*; 38 import javax.management.modelmbean.*; 39 40 public class GetAllDescriptorsTest { 41 42 public static class Resource { 43 public int getNumber() { 44 return number; 45 } 46 47 public void setNumber(int n) { 48 number = n; 49 } 50 51 public int addOne(int x) { 52 return x + 1; 53 } 54 55 public Object[] getArray() { 56 return (Object[]) array.clone(); 57 } 58 59 // doesn't look like an attribute so not seen by caching logic 60 public void tweakArray(Object[] array) { 61 this.array = (Object[]) array.clone(); 62 } 63 64 private int number = 1234; 65 private Object[] array = {"hello", "world"}; 66 } 67 68 public static void main(String[] args) { 69 int errorCount = 0; 70 for (int i = 0; i < NTESTS; i++) { 71 try { 72 System.out.println("Test " + i + ":"); 73 test(i); 74 } catch (Throwable e) { 75 errorCount++; 76 boolean first = true; 77 do { 78 System.err.println(first ? "Exception:" : "Caused by:"); 79 first = false; 80 e.printStackTrace(); 81 Throwable nexte; 82 nexte = e.getCause(); 83 if (nexte == null) { // old JMX 84 if (e instanceof MBeanException) 85 nexte = ((MBeanException) e).getTargetException(); 86 } 87 e = nexte; 88 } while (e != null); 89 } 90 } 91 if (errorCount == 0) { 92 System.out.println("All ModelMBean tests successfuly passed"); 93 System.out.println("Bye! Bye!"); 94 // JTReg doesn't like System.exit(0); 95 return; 96 } else { 97 System.err.println("ERROR: " + errorCount + " tests failed"); 98 System.exit(errorCount); 99 } 100 101 } 102 103 private static void test(int testno) throws Exception { 104 // com.sun.jmx.trace.TraceImplementation.init(2); 105 Resource resource = new Resource(); 106 Class resourceClass = Resource.class; 107 Class rmmbClass = RequiredModelMBean.class; 108 Method setManagedResource = 109 rmmbClass.getMethod("setManagedResource", 110 new Class[] {Object.class, 111 String.class}); 112 Method sendNotification = 113 rmmbClass.getMethod("sendNotification", 114 new Class[] {Notification.class}); 115 Method addAttributeChangeNL = 116 rmmbClass.getMethod("addAttributeChangeNotificationListener", 117 new Class[] {NotificationListener.class, 118 String.class, 119 Object.class}); 120 Method getArray = resourceClass.getMethod("getArray", new Class[0]); 121 Method getNumber = resourceClass.getMethod("getNumber", new Class[0]); 122 Method setNumber = 123 resourceClass.getMethod("setNumber", new Class[] {Integer.TYPE}); 124 Method tweakArray = 125 resourceClass.getMethod("tweakArray", 126 new Class[] {Object[].class}); 127 Method addOne = 128 resourceClass.getMethod("addOne", new Class[] {Integer.TYPE}); 129 MBeanServer mbs = MBeanServerFactory.newMBeanServer(); 130 ObjectName on = new ObjectName("a:b=c"); 131 Descriptor attrDescr = new DescriptorSupport(); 132 attrDescr.setField("name", "Array"); 133 attrDescr.setField("descriptorType", "attribute"); 134 attrDescr.setField("getMethod", "getArray"); 135 ModelMBeanAttributeInfo attrInfo = 136 new ModelMBeanAttributeInfo("Array", "array attr", getArray, 137 null, attrDescr); 138 Descriptor attrDescr2 = new DescriptorSupport(); 139 attrDescr2.setField("name", "Number"); 140 attrDescr2.setField("descriptorType", "attribute"); 141 attrDescr2.setField("getMethod", "getNumber"); 142 attrDescr2.setField("setMethod", "setNumber"); 143 ModelMBeanAttributeInfo attrInfo2 = 144 new ModelMBeanAttributeInfo("Number", "number attr", getNumber, 145 setNumber, attrDescr2); 146 Descriptor attrDescr3 = new DescriptorSupport(); 147 attrDescr3.setField("name", "Local"); 148 attrDescr3.setField("descriptorType", "attribute"); 149 attrDescr3.setField("currencyTimeLimit", "" + Integer.MAX_VALUE); 150 ModelMBeanAttributeInfo attrInfo3 = 151 new ModelMBeanAttributeInfo("Local", "java.lang.String", 152 "local attr", true, true, false, 153 attrDescr3); 154 Descriptor attrDescr4 = new DescriptorSupport(); 155 attrDescr4.setField("name", "Local2"); 156 attrDescr4.setField("descriptorType", "attribute"); 157 ModelMBeanAttributeInfo attrInfo4 = 158 new ModelMBeanAttributeInfo("Local2", "java.lang.String", 159 "local attr 2", true, true, false, 160 attrDescr4); 161 ModelMBeanAttributeInfo[] attrs = 162 new ModelMBeanAttributeInfo[] {attrInfo, attrInfo2, attrInfo3, 163 attrInfo4}; 164 ModelMBeanOperationInfo operInfo = 165 new ModelMBeanOperationInfo("getArray descr", getArray); 166 ModelMBeanOperationInfo operInfo2 = 167 new ModelMBeanOperationInfo("getNumber descr", getNumber); 168 ModelMBeanOperationInfo operInfo3 = 169 new ModelMBeanOperationInfo("addOne descr", addOne); 170 ModelMBeanOperationInfo operInfo4 = 171 new ModelMBeanOperationInfo("setNumber descr", setNumber); 172 ModelMBeanOperationInfo operInfo5 = 173 new ModelMBeanOperationInfo("tweakArray descr", tweakArray); 174 ModelMBeanOperationInfo operInfoSetManagedResource = 175 new ModelMBeanOperationInfo("setManagedResource descr", 176 setManagedResource); 177 ModelMBeanOperationInfo operInfoSendNotification = 178 new ModelMBeanOperationInfo("sendNotification descr", 179 sendNotification); 180 ModelMBeanOperationInfo operInfoAddAttributeChangeNL = 181 new ModelMBeanOperationInfo("AddAttributeChangeNL descr", 182 addAttributeChangeNL); 183 ModelMBeanOperationInfo[] opers = 184 new ModelMBeanOperationInfo[] {operInfo, operInfo2, operInfo3, 185 operInfo4, operInfo5, 186 operInfoSetManagedResource, 187 operInfoSendNotification, 188 operInfoAddAttributeChangeNL}; 189 ModelMBeanInfo info = 190 new ModelMBeanInfoSupport(Resource.class.getName(), 191 "Resourcish resource", 192 attrs, null, opers, null, 193 null); 194 mbs.createMBean(RequiredModelMBean.class.getName(), 195 on, 196 new Object[] {info}, 197 new String[] {ModelMBeanInfo.class.getName()}); 198 mbs.invoke(on, "setManagedResource", 199 new Object[] {resource, "objectReference"}, 200 new String[] {"java.lang.Object", "java.lang.String"}); 201 switch (testno) { 202 case 0: { 203 /* Check getDescriptors("") on original MBeanInfo */ 204 final Descriptor[] desc = info.getDescriptors(""); 205 checkDescriptors(info,desc,"info.getDescriptors(\"\")"); 206 break; 207 } 208 case 1: { 209 /* Check getDescriptors(null) on original MBeanInfo */ 210 final Descriptor[] desc = info.getDescriptors(null); 211 checkDescriptors(info,desc,"info.getDescriptors(null)"); 212 break; 213 } 214 case 2: { 215 /* Check getDescriptors("") on retrieved MBeanInfo */ 216 final MBeanInfo mbi = mbs.getMBeanInfo(on); 217 final ModelMBeanInfo model = (ModelMBeanInfo)mbi; 218 final Descriptor[] desc = model.getDescriptors(""); 219 checkDescriptors(info,desc,"model.getDescriptors(\"\")"); 220 break; 221 } 222 case 3: { 223 /* Check getDescriptors(null) on retrieved MBeanInfo */ 224 final MBeanInfo mbi = mbs.getMBeanInfo(on); 225 final ModelMBeanInfo model = (ModelMBeanInfo)mbi; 226 final Descriptor[] desc = model.getDescriptors(null); 227 checkDescriptors(info,desc,"model.getDescriptors(null)"); 228 break; 229 } 230 default: 231 System.err.println("UNKNOWN TEST NUMBER " + testno); 232 break; 233 } 234 } 235 236 /* Removes descriptor from the list and returns it. Returns {@code null} 237 if descriptor is not found */ 238 private static Descriptor remove(ArrayList<Descriptor> list, 239 Descriptor item) { 240 if (list.remove(item)) return item; 241 else return null; 242 } 243 244 /* Check that all descriptors have been returned */ 245 private static void checkDescriptors(ModelMBeanInfo modelMBeanInfo, 246 Descriptor[] descriptors, String string) { 247 int errCount = 0; 248 final ArrayList<Descriptor> list = 249 new ArrayList<Descriptor>(descriptors.length); 250 list.addAll(Arrays.asList(descriptors)); 251 System.out.println("Got " + list.size() + " descriptors for "+string); 252 253 // checks that MBean's descriptor is returned. 254 // 255 final Descriptor mbd = ((MBeanInfo)modelMBeanInfo).getDescriptor(); 256 if (!mbd.equals(remove(list,mbd))) { 257 System.err.println("modelMBeanInfo.getDescriptor(): not found"); 258 errCount++; 259 } 260 261 // checks that MBean's attributes descriptors are returned. 262 // 263 final MBeanAttributeInfo[] attrs = modelMBeanInfo.getAttributes(); 264 for (MBeanAttributeInfo att : attrs) { 265 final Descriptor ad = att.getDescriptor(); 266 final String name = att.getName(); 267 if (!ad.equals(remove(list,ad))) { 268 System.err.println("attInfo.getDescriptor(): not found for "+ 269 name); 270 errCount++; 271 } 272 } 273 274 // checks that MBean's operations descriptors are returned. 275 // 276 final MBeanOperationInfo[] ops = modelMBeanInfo.getOperations(); 277 for (MBeanOperationInfo op : ops) { 278 final Descriptor od = op.getDescriptor(); 279 final String name = op.getName(); 280 if (!od.equals(remove(list,od))) { 281 System.err.println("opInfo.getDescriptor(): not found for "+ 282 name); 283 errCount++; 284 } 285 } 286 287 // checks that MBean's notifications descriptors are returned. 288 // 289 final MBeanNotificationInfo[] ntfs = modelMBeanInfo.getNotifications(); 290 for (MBeanNotificationInfo ntf : ntfs) { 291 final Descriptor nd = ntf.getDescriptor(); 292 final String name = ntf.getName(); 293 if (!nd.equals(remove(list,nd))) { 294 System.err.println("notifInfo.getDescriptor(): not found for "+ 295 name); 296 errCount++; 297 } 298 } 299 if (errCount > 0) { 300 throw new RuntimeException(string+": failed with "+errCount+ 301 " errors"); 302 } else if (list.size() != 0) { 303 // Check that there are no additional descriptors 304 // 305 throw new RuntimeException(string+ 306 ": Unexpected remaining descriptors: "+list); 307 } else System.out.println(string+": PASSED"); 308 } 309 310 private static final int NTESTS = 4; 311 312 }