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 6337061 27 * @summary Test that ModelMBeanInfoSupport.getDescriptors(null) also 28 * returns the MBean's descriptor. 29 * @author Eamonn McManus, Daniel Fuchs 30 * 31 * @run clean GetAllDescriptorsTest 32 * @run build GetAllDescriptorsTest 33 * @run main/othervm/java.security.policy=policy GetAllDescriptorsTest 34 */ 35 36 import java.lang.reflect.*; 37 import java.util.*; 38 import javax.management.*; 39 import javax.management.modelmbean.*; 40 41 public class GetAllDescriptorsTest { 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 getDescriptors("") on original MBeanInfo */ 205 final Descriptor[] desc = info.getDescriptors(""); 206 checkDescriptors(info,desc,"info.getDescriptors(\"\")"); 207 break; 208 } 209 case 1: { 210 /* Check getDescriptors(null) on original MBeanInfo */ 211 final Descriptor[] desc = info.getDescriptors(null); 212 checkDescriptors(info,desc,"info.getDescriptors(null)"); 213 break; 214 } 215 case 2: { 216 /* Check getDescriptors("") on retrieved MBeanInfo */ 217 final MBeanInfo mbi = mbs.getMBeanInfo(on); 218 final ModelMBeanInfo model = (ModelMBeanInfo)mbi; 219 final Descriptor[] desc = model.getDescriptors(""); 220 checkDescriptors(info,desc,"model.getDescriptors(\"\")"); 221 break; 222 } 223 case 3: { 224 /* Check getDescriptors(null) on retrieved MBeanInfo */ 225 final MBeanInfo mbi = mbs.getMBeanInfo(on); 226 final ModelMBeanInfo model = (ModelMBeanInfo)mbi; 227 final Descriptor[] desc = model.getDescriptors(null); 228 checkDescriptors(info,desc,"model.getDescriptors(null)"); 229 break; 230 } 231 default: 232 System.err.println("UNKNOWN TEST NUMBER " + testno); 233 break; 234 } 235 } 236 237 /* Removes descriptor from the list and returns it. Returns {@code null} 238 if descriptor is not found */ 239 private static Descriptor remove(ArrayList<Descriptor> list, 240 Descriptor item) { 241 if (list.remove(item)) return item; 242 else return null; 243 } 244 245 /* Check that all descriptors have been returned */ 246 private static void checkDescriptors(ModelMBeanInfo modelMBeanInfo, 247 Descriptor[] descriptors, String string) { 248 int errCount = 0; 249 final ArrayList<Descriptor> list = 250 new ArrayList<Descriptor>(descriptors.length); 251 list.addAll(Arrays.asList(descriptors)); 252 System.out.println("Got " + list.size() + " descriptors for "+string); 253 254 // checks that MBean's descriptor is returned. 255 // 256 final Descriptor mbd = ((MBeanInfo)modelMBeanInfo).getDescriptor(); 257 if (!mbd.equals(remove(list,mbd))) { 258 System.err.println("modelMBeanInfo.getDescriptor(): not found"); 259 errCount++; 260 } 261 262 // checks that MBean's attributes descriptors are returned. 263 // 264 final MBeanAttributeInfo[] attrs = modelMBeanInfo.getAttributes(); 265 for (MBeanAttributeInfo att : attrs) { 266 final Descriptor ad = att.getDescriptor(); 267 final String name = att.getName(); 268 if (!ad.equals(remove(list,ad))) { 269 System.err.println("attInfo.getDescriptor(): not found for "+ 270 name); 271 errCount++; 272 } 273 } 274 275 // checks that MBean's operations descriptors are returned. 276 // 277 final MBeanOperationInfo[] ops = modelMBeanInfo.getOperations(); 278 for (MBeanOperationInfo op : ops) { 279 final Descriptor od = op.getDescriptor(); 280 final String name = op.getName(); 281 if (!od.equals(remove(list,od))) { 282 System.err.println("opInfo.getDescriptor(): not found for "+ 283 name); 284 errCount++; 285 } 286 } 287 288 // checks that MBean's notifications descriptors are returned. 289 // 290 final MBeanNotificationInfo[] ntfs = modelMBeanInfo.getNotifications(); 291 for (MBeanNotificationInfo ntf : ntfs) { 292 final Descriptor nd = ntf.getDescriptor(); 293 final String name = ntf.getName(); 294 if (!nd.equals(remove(list,nd))) { 295 System.err.println("notifInfo.getDescriptor(): not found for "+ 296 name); 297 errCount++; 298 } 299 } 300 if (errCount > 0) { 301 throw new RuntimeException(string+": failed with "+errCount+ 302 " errors"); 303 } else if (list.size() != 0) { 304 // Check that there are no additional descriptors 305 // 306 throw new RuntimeException(string+ 307 ": Unexpected remaining descriptors: "+list); 308 } else System.out.println(string+": PASSED"); 309 } 310 311 private static final int NTESTS = 4; 312 313 }