J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright 2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
| 21 | * have any 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 | } |