/*
 * Copyright 2000-2001 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 4289544
 * @summary ActivationGroupImpl.newInstance does not set context classloader for impl
 *
 * @author Laird Dornin; code borrowed from Ann Wollrath
 *
 * @library ../../../testlibrary
 * @build TestLibrary RMID JavaVM StreamPipe
 * @build MyRMI
 * @build CheckImplClassLoader ActivatableImpl
 * @build ActivatableImpl ActivatableImpl_Stub
 * @run main/othervm/policy=security.policy/timeout=150 CheckImplClassLoader
 */

import java.io.*;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.activation.*;
import java.net.URL;

/**
 * sun.rmi.server.ActivationGroupImpl.newInstance() needs to set the
 * context class loader when it constructs the implementation class of
 * an Activatable object.  It needs to set the ccl to be the class
 * loader of the implementation class.
 *
 * Test creates an Activatable object whose impl is loaded outside of
 * CLASSPATH.  The impls constructor checks to make sure that the
 * correct context class loader has been set when the constructor is
 * invoked.
 */
public class CheckImplClassLoader {

    private static Object dummy = new Object();
    private static MyRMI myRMI = null;
    private static ActivationGroup group = null;

    public static void main(String args[]) {
        /*
         * The following line is required with the JDK 1.2 VM because
         * of gc hocus pocus that may no longer be needed with an
         * exact vm (hotspot).
         */
        Object dummy1 = new Object();
        RMID rmid = null;

        System.err.println("\nRegression test for bug/rfe 4289544\n");

        try {

            URL implcb = TestLibrary.installClassInCodebase("ActivatableImpl",
                                                            "implcb");
            TestLibrary.installClassInCodebase("ActivatableImpl_Stub",
                                               "implcb");
            TestLibrary.suggestSecurityManager(
                TestParams.defaultSecurityManager);

            RMID.removeLog();
            rmid = RMID.createRMID();
            rmid.start();

            System.err.println("Create activation group in this VM");
            ActivationGroupDesc groupDesc =
                new ActivationGroupDesc(null, null);
            ActivationSystem system = ActivationGroup.getSystem();
            ActivationGroupID groupID = system.registerGroup(groupDesc);
            group = ActivationGroup.createGroup(groupID, groupDesc, 0);

            ActivationDesc desc = new ActivationDesc("ActivatableImpl",
                                                     implcb.toString(), null);
            myRMI = (MyRMI) Activatable.register(desc);

            System.err.println("Checking that impl has correct " +
                               "context class loader");
            if (!myRMI.classLoaderOk()) {
                TestLibrary.bomb("incorrect context class loader for " +
                                 "activation constructor");
            }

            System.err.println("Deactivate object via method call");
            myRMI.shutdown();

            System.err.println("\nsuccess: CheckImplClassLoader test passed ");

        } catch (Exception e) {
            TestLibrary.bomb("\nfailure: unexpected exception ", e);
        } finally {
            try {
                Thread.sleep(4000);
            } catch (InterruptedException e) {
            }

            myRMI = null;
            System.err.println("rmid shut down");
            ActivationLibrary.rmidCleanup(rmid);
            TestLibrary.unexport(group);
        }
    }
}
