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 6204469 27 * @summary Check that descriptors have not broken serial interop. 28 * @author Eamonn McManus 29 * @modules java.management 30 * @run clean MBeanInfoInteropTest SerializedInfo 31 * @run build MBeanInfoInteropTest SerializedInfo 32 * @run main MBeanInfoInteropTest SerializedInfo 33 */ 34 35 /* 36 * When run with just a classname argument ("SerializedInfo" above), 37 * this reads the serialized objects from that class. 38 * When run with the argument "generate" and a classname, say "SerializedInfo", 39 * this creates the class SerializedInfo.java. The idea is to do that on JDK 5.0 40 * then run this test on the latest JDK, or vice versa. The 41 * copy included in this source directory was generated on JDK 5.0 42 * so that we continue to check forward interop (serialize on JDK 5, 43 * deserialize on JDK 6). There is no easy way to automate backward 44 * interop checking. 45 */ 46 47 import java.io.ByteArrayInputStream; 48 import java.io.ByteArrayOutputStream; 49 import java.io.ObjectInputStream; 50 import java.io.ObjectOutputStream; 51 import java.io.PrintWriter; 52 import java.io.Serializable; 53 import java.lang.reflect.Field; 54 import java.lang.reflect.Modifier; 55 import javax.management.Descriptor; 56 import javax.management.MBeanAttributeInfo; 57 import javax.management.MBeanConstructorInfo; 58 import javax.management.MBeanInfo; 59 import javax.management.MBeanNotificationInfo; 60 import static javax.management.MBeanOperationInfo.*; 61 import static javax.management.openmbean.SimpleType.INTEGER; 62 import javax.management.MBeanOperationInfo; 63 import javax.management.MBeanParameterInfo; 64 import javax.management.modelmbean.DescriptorSupport; 65 import javax.management.modelmbean.ModelMBeanAttributeInfo; 66 import javax.management.modelmbean.ModelMBeanConstructorInfo; 67 import javax.management.modelmbean.ModelMBeanInfoSupport; 68 import javax.management.modelmbean.ModelMBeanNotificationInfo; 69 import javax.management.modelmbean.ModelMBeanOperationInfo; 70 import javax.management.openmbean.OpenMBeanAttributeInfo; 71 import javax.management.openmbean.OpenMBeanAttributeInfoSupport; 72 import javax.management.openmbean.OpenMBeanConstructorInfo; 73 import javax.management.openmbean.OpenMBeanConstructorInfoSupport; 74 import javax.management.openmbean.OpenMBeanInfoSupport; 75 import javax.management.openmbean.OpenMBeanOperationInfo; 76 import javax.management.openmbean.OpenMBeanOperationInfoSupport; 77 import javax.management.openmbean.OpenMBeanParameterInfo; 78 import javax.management.openmbean.OpenMBeanParameterInfoSupport; 79 80 public class MBeanInfoInteropTest { 81 public static void main(String[] args) throws Exception { 82 if (args.length == 2 && args[0].equals("generate")) 83 generate(args[1]); 84 else if (args.length == 1) 85 test(args[0]); 86 else { 87 final String usage = 88 "Usage: MBeanInfoInteropTest [generate] ClassName"; 89 throw new Exception(usage); 90 } 91 } 92 93 private static void test(String className) throws Exception { 94 Class<?> c = Class.forName(className); 95 Field f = c.getField("BYTES"); 96 byte[] bytes = (byte[]) f.get(null); 97 ByteArrayInputStream bis = new ByteArrayInputStream(bytes); 98 ObjectInputStream ois = new ObjectInputStream(bis); 99 boolean matched = true; 100 for (Serializable s : objects) { 101 Object o = ois.readObject(); 102 if (!o.equals(s)) { 103 showMismatch(o, s); 104 matched = false; 105 } 106 } 107 if (!matched) 108 throw new Exception("Read objects did not match"); 109 System.out.println("Test passed"); 110 } 111 112 private static void showMismatch(Object read, Serializable expected) 113 throws Exception { 114 String name = "<unknown>"; 115 Field[] fs = MBeanInfoInteropTest.class.getDeclaredFields(); 116 for (Field f : fs) { 117 if (!Modifier.isStatic(f.getModifiers())) 118 continue; 119 Object x = f.get(null); 120 if (x == expected) { 121 name = f.getName(); 122 break; 123 } 124 } 125 System.out.println("Read object mismatch for field " + name); 126 System.out.println("...read: " + read); 127 System.out.println("...expected: " + expected); 128 } 129 130 private static void generate(String className) throws Exception { 131 System.out.println("Generating " + className + ".java"); 132 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 133 ObjectOutputStream oos = new ObjectOutputStream(bos); 134 for (Serializable s : objects) 135 oos.writeObject(s); 136 oos.close(); 137 byte[] bytes = bos.toByteArray(); 138 PrintWriter pw = new PrintWriter(className + ".java"); 139 pw.printf( 140 "// Generated by: MBeanInfoInteropTest generate %s\n" + 141 "import java.io.*;\n" + 142 "public class %s {\n" + 143 "public static final byte[] BYTES = {\n", className, className); 144 for (int i = 0; i < bytes.length; i++) { 145 byte b = bytes[i]; 146 pw.printf("%d,", b); 147 if (i % 16 == 15) 148 pw.printf("\n"); 149 } 150 pw.printf("\n"); 151 pw.printf( 152 "};\n" + 153 "}\n"); 154 pw.close(); 155 System.out.println("...done"); 156 } 157 158 private static MBeanAttributeInfo mbai; 159 private static MBeanParameterInfo mbpi; 160 private static MBeanConstructorInfo mbci1, mbci2; 161 private static MBeanNotificationInfo mbni1, mbni2; 162 private static MBeanOperationInfo mboi1, mboi2; 163 private static MBeanInfo mbi1, mbi2; 164 private static OpenMBeanAttributeInfoSupport ombai1, ombai2, ombai3, ombai4; 165 private static OpenMBeanParameterInfoSupport ombpi1, ombpi2, ombpi3, ombpi4; 166 private static OpenMBeanConstructorInfoSupport ombci1, ombci2; 167 private static OpenMBeanOperationInfoSupport omboi1, omboi2; 168 private static OpenMBeanInfoSupport ombi1, ombi2; 169 private static ModelMBeanAttributeInfo mmbai1, mmbai2; 170 private static ModelMBeanConstructorInfo mmbci1, mmbci2, mmbci3, mmbci4; 171 private static ModelMBeanOperationInfo mmboi1, mmboi2, mmboi3, mmboi4; 172 private static ModelMBeanNotificationInfo mmbni1, mmbni2, mmbni3, mmbni4; 173 private static ModelMBeanInfoSupport mmbi1, mmbi2, mmbi3, mmbi4; 174 private static Serializable[] objects; 175 static { 176 try { 177 init(); 178 } catch (Exception e) { 179 throw new IllegalArgumentException("unexpected", e); 180 } 181 } 182 private static void init() throws Exception { 183 mbai = 184 new MBeanAttributeInfo("name", "type", "descr", true, false, false); 185 mbpi = 186 new MBeanParameterInfo("name", "type", "descr"); 187 MBeanParameterInfo[] params = new MBeanParameterInfo[] {mbpi}; 188 mbci1 = 189 new MBeanConstructorInfo("name", "descr", null); 190 mbci2 = 191 new MBeanConstructorInfo("name", "descr", params); 192 mbni1 = 193 new MBeanNotificationInfo(null, "name", "descr"); 194 mbni2 = 195 new MBeanNotificationInfo(new String[] {"type"}, "name", "descr"); 196 mboi1 = 197 new MBeanOperationInfo("name", "descr", null, "type", ACTION); 198 mboi2 = 199 new MBeanOperationInfo("name", "descr", params, "type", INFO); 200 mbi1 = 201 new MBeanInfo("class", "descr", null, null, null, null); 202 mbi2 = 203 new MBeanInfo( 204 "class", "descr", 205 new MBeanAttributeInfo[] {mbai}, 206 new MBeanConstructorInfo[] {mbci1, mbci2}, 207 new MBeanOperationInfo[] {mboi1, mboi2}, 208 new MBeanNotificationInfo[] {mbni1, mbni2}); 209 210 ombai1 = 211 new OpenMBeanAttributeInfoSupport("name", "descr", INTEGER, 212 true, false, false); 213 ombai2 = 214 new OpenMBeanAttributeInfoSupport("name", "descr", INTEGER, 215 true, false, false, 5); 216 ombai3 = 217 new OpenMBeanAttributeInfoSupport("name", "descr", INTEGER, 218 true, false, false, 5, 1, 6); 219 ombai4 = 220 new OpenMBeanAttributeInfoSupport("name", "descr", INTEGER, 221 true, false, false, 5, 222 new Integer[] {2, 3, 5, 7}); 223 ombpi1 = 224 new OpenMBeanParameterInfoSupport("name1", "descr", INTEGER); 225 ombpi2 = 226 new OpenMBeanParameterInfoSupport("name2", "descr", INTEGER, 5); 227 ombpi3 = 228 new OpenMBeanParameterInfoSupport("name3", "descr", INTEGER, 5, 1, 6); 229 ombpi4 = 230 new OpenMBeanParameterInfoSupport("name4", "descr", INTEGER, 5, 231 new Integer[] {2, 3, 5, 7}); 232 OpenMBeanParameterInfo[] oparams = {ombpi1, ombpi2, ombpi3, ombpi4}; 233 ombci1 = 234 new OpenMBeanConstructorInfoSupport("name", "descr", null); 235 ombci2 = 236 new OpenMBeanConstructorInfoSupport("name", "descr", oparams); 237 omboi1 = 238 new OpenMBeanOperationInfoSupport("name", "descr", null, 239 INTEGER, ACTION); 240 omboi2 = 241 new OpenMBeanOperationInfoSupport("name", "descr", oparams, 242 INTEGER, ACTION); 243 ombi1 = 244 new OpenMBeanInfoSupport("class", "descr", null, null, null, null); 245 ombi2 = 246 new OpenMBeanInfoSupport( 247 "class", "descr", 248 new OpenMBeanAttributeInfo[] {ombai1, ombai2, ombai3, ombai4}, 249 new OpenMBeanConstructorInfo[] {ombci1, ombci2}, 250 new OpenMBeanOperationInfo[] {omboi1, omboi2}, 251 new MBeanNotificationInfo[] {mbni1, mbni2}); 252 253 Descriptor attrd = new DescriptorSupport(new String[] { 254 "name=name", "descriptorType=attribute", 255 }); 256 mmbai1 = 257 new ModelMBeanAttributeInfo("name", "type", "descr", 258 true, false, false); 259 mmbai2 = 260 new ModelMBeanAttributeInfo("name", "type", "descr", 261 true, false, false, attrd); 262 Descriptor constrd = new DescriptorSupport(new String[] { 263 "name=name", "descriptorType=operation", "role=constructor", 264 }); 265 mmbci1 = 266 new ModelMBeanConstructorInfo("name", "descr", null); 267 mmbci2 = 268 new ModelMBeanConstructorInfo("name", "descr", null, constrd); 269 mmbci3 = 270 new ModelMBeanConstructorInfo("name", "descr", params); 271 mmbci4 = 272 new ModelMBeanConstructorInfo("name", "descr", params, constrd); 273 Descriptor operd = new DescriptorSupport(new String[] { 274 "name=name", "descriptorType=operation", 275 }); 276 mmboi1 = 277 new ModelMBeanOperationInfo("name", "descr", null, "type", ACTION); 278 mmboi2 = 279 new ModelMBeanOperationInfo("name", "descr", null, "type", ACTION, 280 operd); 281 mmboi3 = 282 new ModelMBeanOperationInfo("name", "descr", params, "type", ACTION); 283 mmboi4 = 284 new ModelMBeanOperationInfo("name", "descr", params, "type", ACTION, 285 operd); 286 Descriptor notifd = new DescriptorSupport(new String[] { 287 "name=name", "descriptorType=notification", 288 }); 289 mmbni1 = 290 new ModelMBeanNotificationInfo(null, "name", "descr"); 291 mmbni2 = 292 new ModelMBeanNotificationInfo(null, "name", "descr", notifd); 293 mmbni3 = 294 new ModelMBeanNotificationInfo(new String[] {"type"}, "name", "descr"); 295 mmbni4 = 296 new ModelMBeanNotificationInfo(new String[] {"type"}, "name", 297 "descr", notifd); 298 Descriptor mbeand = new DescriptorSupport(new String[] { 299 "name=name", "descriptorType=mbean", 300 }); 301 mmbi1 = 302 new ModelMBeanInfoSupport("class", "descr", null, null, null, null); 303 mmbi2 = 304 new ModelMBeanInfoSupport("class", "descr", null, null, null, null, 305 mbeand); 306 mmbi3 = 307 new ModelMBeanInfoSupport( 308 "class", "descr", 309 new ModelMBeanAttributeInfo[] {mmbai1, mmbai2}, 310 new ModelMBeanConstructorInfo[] {mmbci1, mmbci2, mmbci3, mmbci4}, 311 new ModelMBeanOperationInfo[] {mmboi1, mmboi2, mmboi3, mmboi4}, 312 new ModelMBeanNotificationInfo[] {mmbni1, mmbni2, mmbni3, mmbni4}); 313 mmbi4 = 314 new ModelMBeanInfoSupport( 315 "class", "descr", 316 new ModelMBeanAttributeInfo[] {mmbai1, mmbai2}, 317 new ModelMBeanConstructorInfo[] {mmbci1, mmbci2, mmbci3, mmbci4}, 318 new ModelMBeanOperationInfo[] {mmboi1, mmboi2, mmboi3, mmboi4}, 319 new ModelMBeanNotificationInfo[] {mmbni1, mmbni2, mmbni3, mmbni4}, 320 mbeand); 321 322 objects = new Serializable[] { 323 mbai, mbpi, mbci1, mbci2, mbni1, mbni2, mboi1, mboi2, mbi1, mbi2, 324 325 ombai1, ombai2, ombai3, ombai4, 326 ombpi1, ombpi2, ombpi3, ombpi4, 327 ombci1, ombci2, 328 omboi1, omboi2, 329 ombi1, ombi2, 330 331 mmbai1, mmbai2, 332 mmbci1, mmbci2, mmbci3, mmbci4, 333 mmboi1, mmboi2, mmboi3, mmboi4, 334 mmbni1, mmbni2, mmbni3, mmbni4, 335 }; 336 } 337 }