/*
 * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @bug 4974913
 * @summary Test that array classes can be found in signatures always
 * and can be deserialized by the deprecated MBeanServer.deserialize method
 * @author Eamonn McManus
 * @run clean ArrayClassTest
 * @run build ArrayClassTest
 * @run main ArrayClassTest
 */

import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import javax.management.*;
import javax.management.loading.*;

public class ArrayClassTest {
    public static void main(String[] args) throws Exception {
        MBeanServer mbs = MBeanServerFactory.createMBeanServer();

        /* If this test isn't loaded by a URLClassLoader we will get
           a ClassCastException here, which is good because it means
           this test isn't valid.  */
        URLClassLoader testLoader =
            (URLClassLoader) ArrayClassTest.class.getClassLoader();

        // Create an MLet that can load the same class names but
        // will produce different results.
        ClassLoader loader = new SpyLoader(testLoader.getURLs());
        ObjectName loaderName = new ObjectName("test:type=SpyLoader");
        mbs.registerMBean(loader, loaderName);

        ObjectName testName = new ObjectName("test:type=Test");
        mbs.createMBean(Test.class.getName(), testName, loaderName,
                        new Object[1], new String[] {X[].class.getName()});
        ClassLoader checkLoader = mbs.getClassLoaderFor(testName);
        if (checkLoader != loader)
            throw new AssertionError("Wrong loader: " + checkLoader);

        mbs.invoke(testName, "ignore", new Object[1],
                   new String[] {Y[].class.getName()});

        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ObjectOutputStream oout = new ObjectOutputStream(bout);
        oout.writeObject(new Z[0]);
        oout.close();
        byte[] bytes = bout.toByteArray();
        ObjectInputStream oin = mbs.deserialize(testName, bytes);
        Object zarray = oin.readObject();
        String failed = null;
        if (zarray instanceof Z[])
            failed = "read back a real Z[]";
        else if (!zarray.getClass().getName().equals(Z[].class.getName())) {
            failed = "returned object of wrong type: " +
                zarray.getClass().getName();
        } else if (Array.getLength(zarray) != 0)
            failed = "returned array of wrong size: " + Array.getLength(zarray);
        if (failed != null) {
            System.out.println("TEST FAILED: " + failed);
            System.exit(1);
        }

        System.out.println("Test passed");
    }

    public static interface TestMBean {
        public void ignore(Y[] ignored);
    }

    public static class Test implements TestMBean {
        public Test(X[] ignored) {}
        public void ignore(Y[] ignored) {}
    }

    public static class X {}
    public static class Y {}
    public static class Z implements Serializable {}

    public static interface SpyLoaderMBean {}

    /* We originally had this extend MLet but for some reason that
       stopped the bug from happening.  Some side-effect of registering
       the MLet in the MBean server caused it not to fail when asked
       to load Z[].  */
    public static class SpyLoader extends URLClassLoader
            implements SpyLoaderMBean, PrivateClassLoader {
        public SpyLoader(URL[] urls) {
            // important that the parent classloader be null!
            // otherwise we can pick up classes from the classpath
            super(urls, null);
        }

        /*
        public Class loadClass(String name) throws ClassNotFoundException {
            System.out.println("loadClass: " + name);
            return super.loadClass(name);
        }

        public Class loadClass(String name, boolean resolve)
                throws ClassNotFoundException {
            System.out.println("loadClass: " + name + ", " + resolve);
            return super.loadClass(name, resolve);
        }
        */

        public Class findClass(String name) throws ClassNotFoundException {
            System.out.println("findClass: " + name);
            if (false)
                new Throwable().printStackTrace(System.out);
            Class c = super.findClass(name);
            System.out.println(" -> " + name + " (" + c.getClassLoader() + ")");
            return c;
        }
    }
}
