1 /* 2 * Copyright (c) 2004, 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 4974913 27 * @summary Test that array classes can be found in signatures always 28 * and can be deserialized by the deprecated MBeanServer.deserialize method 29 * @author Eamonn McManus 30 * 31 * @run clean ArrayClassTest 32 * @run build ArrayClassTest 33 * @run main ArrayClassTest 34 */ 35 36 import java.io.*; 37 import java.lang.reflect.*; 38 import java.net.*; 39 import java.nio.file.Paths; 40 import javax.management.*; 41 import javax.management.loading.*; 42 43 public class ArrayClassTest { main(String[] args)44 public static void main(String[] args) throws Exception { 45 MBeanServer mbs = MBeanServerFactory.createMBeanServer(); 46 47 String[] cpaths = System.getProperty("test.classes", ".") 48 .split(File.pathSeparator); 49 URL[] urls = new URL[cpaths.length]; 50 for (int i=0; i < cpaths.length; i++) { 51 urls[i] = Paths.get(cpaths[i]).toUri().toURL(); 52 } 53 54 // Create an MLet that can load the same class names but 55 // will produce different results. 56 ClassLoader loader = new SpyLoader(urls); 57 ObjectName loaderName = new ObjectName("test:type=SpyLoader"); 58 mbs.registerMBean(loader, loaderName); 59 60 ObjectName testName = new ObjectName("test:type=Test"); 61 mbs.createMBean(Test.class.getName(), testName, loaderName, 62 new Object[1], new String[] {X[].class.getName()}); 63 ClassLoader checkLoader = mbs.getClassLoaderFor(testName); 64 if (checkLoader != loader) 65 throw new AssertionError("Wrong loader: " + checkLoader); 66 67 mbs.invoke(testName, "ignore", new Object[1], 68 new String[] {Y[].class.getName()}); 69 70 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 71 ObjectOutputStream oout = new ObjectOutputStream(bout); 72 oout.writeObject(new Z[0]); 73 oout.close(); 74 byte[] bytes = bout.toByteArray(); 75 ObjectInputStream oin = mbs.deserialize(testName, bytes); 76 Object zarray = oin.readObject(); 77 String failed = null; 78 if (zarray instanceof Z[]) 79 failed = "read back a real Z[]"; 80 else if (!zarray.getClass().getName().equals(Z[].class.getName())) { 81 failed = "returned object of wrong type: " + 82 zarray.getClass().getName(); 83 } else if (Array.getLength(zarray) != 0) 84 failed = "returned array of wrong size: " + Array.getLength(zarray); 85 if (failed != null) { 86 System.out.println("TEST FAILED: " + failed); 87 System.exit(1); 88 } 89 90 System.out.println("Test passed"); 91 } 92 93 public static interface TestMBean { ignore(Y[] ignored)94 public void ignore(Y[] ignored); 95 } 96 97 public static class Test implements TestMBean { Test(X[] ignored)98 public Test(X[] ignored) {} ignore(Y[] ignored)99 public void ignore(Y[] ignored) {} 100 } 101 102 public static class X {} 103 public static class Y {} 104 public static class Z implements Serializable {} 105 106 public static interface SpyLoaderMBean {} 107 108 /* We originally had this extend MLet but for some reason that 109 stopped the bug from happening. Some side-effect of registering 110 the MLet in the MBean server caused it not to fail when asked 111 to load Z[]. */ 112 public static class SpyLoader extends URLClassLoader 113 implements SpyLoaderMBean, PrivateClassLoader { SpyLoader(URL[] urls)114 public SpyLoader(URL[] urls) { 115 // important that the parent classloader be null! 116 // otherwise we can pick up classes from the classpath 117 super(urls, null); 118 } 119 120 /* 121 public Class loadClass(String name) throws ClassNotFoundException { 122 System.out.println("loadClass: " + name); 123 return super.loadClass(name); 124 } 125 126 public Class loadClass(String name, boolean resolve) 127 throws ClassNotFoundException { 128 System.out.println("loadClass: " + name + ", " + resolve); 129 return super.loadClass(name, resolve); 130 } 131 */ 132 findClass(String name)133 public Class findClass(String name) throws ClassNotFoundException { 134 System.out.println("findClass: " + name); 135 if (false) 136 new Throwable().printStackTrace(System.out); 137 Class c = super.findClass(name); 138 System.out.println(" -> " + name + " (" + c.getClassLoader() + ")"); 139 return c; 140 } 141 } 142 } 143