/*
 * Copyright 1999 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/* @test
 * @bug 4180392
 * @summary When an instance of java.rmi.RMISecurityManager is set the VM's
 * security manager, the same package access restrictions should be in effect
 * as when the default java.lang.SecurityManager is set, which with the
 * default "java.security" file in the JDK means that access to packages in
 * the sun.* package hierarchy is denied (without explicit runtime permission
 * "accessClassInPackge.*").
 * @author Peter Jones
 *
 * @build CheckPackageAccess
 * @run main/othervm CheckPackageAccess
 */

import java.rmi.RMISecurityManager;

public class CheckPackageAccess {

    /*
     * This test assumes that the default security manager protects untrusted
     * access to classes in the sun.* hierarchy, which is what is specified
     * in the JDK's default java.security file.
     */
    private final static String restrictedClassName = "sun.misc.Ref";

    public static void main(String[] args) {

        System.err.println("\nRegression test for bug 4180392\n");

        System.err.println("Setting RMISecurityManager.");
        System.setSecurityManager(new RMISecurityManager());

        try {
            System.err.println("Attempting to acquire restricted class " +
                restrictedClassName);
            Class restrictedClass = Class.forName(restrictedClassName);
            throw new RuntimeException(
                "TEST FAILED: successfully acquired restricted class " +
                    restrictedClass);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(
                "TEST FAILED: couldn't find (but was allowed to look for) " +
                    "restricted class " + restrictedClassName);
        } catch (SecurityException e) {
            System.err.println("TEST PASSED: ");
            e.printStackTrace();
        }
    }
}
