/*
 * Copyright 1998-2003 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 4110548
 * @summary activate fails if rmid is restarted
 * @author Ann Wollrath
 *
 * @library ../../../testlibrary
 * @build RMID ActivationLibrary TestLibrary
 * @build ActivateMe CheckRegisterInLog CheckRegisterInLog_Stub
 * @run main/othervm/policy=security.policy/timeout=240 CheckRegisterInLog
 */

import java.io.*;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.activation.*;
import sun.rmi.server.ActivatableRef;
import java.lang.reflect.*;
import java.util.Properties;

public class CheckRegisterInLog
        extends Activatable
        implements ActivateMe, Runnable
{

    public CheckRegisterInLog(ActivationID id, MarshalledObject obj)
        throws ActivationException, RemoteException
    {
        super(id, 0);
    }

    public void ping()
    {}

    /**
     * Spawns a thread to deactivate the object.
     */
    public void shutdown() throws Exception
    {
        (new Thread(this,"CheckRegisterInLog")).start();
    }

    /**
     * Thread to deactivate object. First attempts to make object
     * inactive (via the inactive method).  If that fails (the
     * object may still have pending/executing calls), then
     * unexport the object forcibly.
     */
    public void run() {
        ActivationLibrary.deactivate(this, getID());
    }

    public static void main(String[] args)  {
        /*
         * The following line is required with the JDK 1.2 VM so that the
         * VM can exit gracefully when this test completes.  Otherwise, the
         * conservative garbage collector will find a handle to the server
         * object on the native stack and not clear the weak reference to
         * it in the RMI runtime's object table.
         */
        Object dummy = new Object();
        RMID rmid = null;
        ActivateMe obj;

        System.out.println("\nRegression test for bug 4110548\n");

        CheckRegisterInLog server;

        try {
            TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager");

            /*
             * Start up activation system daemon "rmid".
             */
            RMID.removeLog();
            rmid = RMID.createRMID();
            rmid.start();

            /* Cause activation groups to have a security policy that will
             * allow security managers to be downloaded and installed
             */
            Properties p = new Properties();
            // this test must always set policies/managers in its
            // activation groups
            p.put("java.security.policy",
                  TestParams.defaultGroupPolicy);
            p.put("java.security.manager",
                  TestParams.defaultSecurityManager);

            /*
             * Register an activation group and an object
             * in that group.
             */
            System.err.println("Creating group descriptor");
            ActivationGroupDesc groupDesc =
                new ActivationGroupDesc(p, null);
            System.err.println("Registering group");
            ActivationSystem system = ActivationGroup.getSystem();
            ActivationGroupID groupID = system.registerGroup(groupDesc);

            System.err.println("Creating descriptor");
            ActivationDesc desc =
                new ActivationDesc(groupID, "CheckRegisterInLog",
                                   null, null);
            System.err.println("Registering descriptor");
            obj = (ActivateMe)Activatable.register(desc);

            /*
             * Restart rmid to force it to read the log file
             */
            rmid.restart();


            /*
             * 4212096: Give rmid time to go away - we want to make
             * sure that an attempt to activate the test object is not made
             * on the ActivationSystem that is about to be shutdown.
             */
            try {
                Thread.sleep(5000);
            } catch (InterruptedException ie) {
            }

            /*
             * Activate the object via a method call.
             */
            System.err.println("Activate the object via method call");
            obj.ping();

            /*
             * Clean up object too.
             */
            System.err.println("Deactivate object via method call");
            obj.shutdown();

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

        } catch (Exception e) {
            System.err.println("\nfailure: unexpected exception " +
                               e.getClass().getName() + ": " + e.getMessage());
            e.printStackTrace(System.err);
            throw new RuntimeException("CheckRegisterInLog got exception " +
                                       e.getMessage());
        } finally {
            ActivationLibrary.rmidCleanup(rmid);
        }
    }
}
