/*
 * Copyright (c) 1999, 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 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();
        }
    }
}
