/*
 * Copyright 1998-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 4105080
 * @summary Activation retry during a remote method call to an activatable
 *          object can cause infinite recursion in some situations. The
 *          RemoteRef contained in the ActivatableRef should never be
 *          an ActivatableRef, but another type.
 * (Needs /othervm to evade JavaTest security manager --aecolley)
 * @author Ann Wollrath
 *
 * @bug 4164971
 * @summary allow non-public activatable class and/or constructor
 *          Main test class hasa non-public constructor to ensure
 *          functionality is in place
 *
 * @library ../../../testlibrary
 * @build TestLibrary RMID
 * @build ActivateMe CheckActivateRef_Stub CheckActivateRef
 * @run main/othervm/policy=security.policy/timeout=240 -Djava.rmi.server.ignoreStubClasses=true CheckActivateRef
 * @run main/othervm/policy=security.policy/timeout=240 -Djava.rmi.server.ignoreStubClasses=false CheckActivateRef
 */

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 CheckActivateRef
        extends Activatable
        implements ActivateMe, Runnable
{

    private CheckActivateRef(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,"CheckActivateRef")).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;

        // test should tolerate certain types of failures
        int failures = 0;
        int i = 0;

        System.err.println("\nRegression test for bug 4105080\n");
        System.err.println("java.security.policy = " +
                           System.getProperty("java.security.policy",
                                              "no policy"));


        String propValue =
            System.getProperty("java.rmi.server.useDynamicProxies", "false");
        boolean useDynamicProxies = Boolean.parseBoolean(propValue);

        CheckActivateRef server;
        try {
            TestLibrary.suggestSecurityManager(TestParams.defaultSecurityManager);

            // start an 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);
            p.put("java.rmi.server.useDynamicProxies", propValue);

            /*
             * Activate an object by registering its object
             * descriptor and invoking a method on the
             * stub returned from the register call.
             */
            System.err.println("Create activation group in this VM");
            ActivationGroupDesc groupDesc =
                new ActivationGroupDesc(p, null);
            ActivationSystem system = ActivationGroup.getSystem();
            ActivationGroupID groupID = system.registerGroup(groupDesc);
            ActivationGroup.createGroup(groupID, groupDesc, 0);
            System.err.println("Creating descriptor");
            ActivationDesc desc =
                new ActivationDesc("CheckActivateRef", null, null);
            System.err.println("Registering descriptor");
            obj = (ActivateMe) Activatable.register(desc);

            System.err.println("proxy = " + obj);

            if (useDynamicProxies && !Proxy.isProxyClass(obj.getClass()))
            {
                throw new RuntimeException("proxy is not dynamic proxy");
            }

            /*
             * Loop a bunch of times to force activator to
             * spawn VMs (groups)
             */
            try {
                for (; i < 7; i++) {

                    System.err.println("Activate object via method call");

                    /*
                     * Fix for 4277196: if we got an inactive group
                     * exception, it is likely that we accidentally
                     * invoked a method on an old activation
                     * group. Give some time for the group to go away
                     * and then retry the activation.
                     */
                    try {
                        obj.ping();
                    } catch (RemoteException e) {
                        Exception detail = (Exception) e.detail;
                        if ((detail != null) &&
                            (detail instanceof ActivationException) &&
                            (detail.getMessage().equals("group is inactive")))
                        {
                            try {
                                Thread.sleep(5000);
                            } catch (InterruptedException ex) {
                            }
                            obj.ping();

                        } else {
                            throw e;
                        }
                    }

                    System.err.println("proxy = " + obj);

                    /*
                     * Now that object is activated, check to make sure that
                     * the RemoteRef inside the stub's ActivatableRef
                     * is *not* an ActivatableRef.
                     */
                    ActivatableRef aref;
                    if (obj instanceof RemoteStub) {
                        aref = (ActivatableRef) ((RemoteObject) obj).getRef();
                    } else if (Proxy.isProxyClass(obj.getClass())) {
                        RemoteObjectInvocationHandler handler =
                            (RemoteObjectInvocationHandler)
                            Proxy.getInvocationHandler(obj);
                        aref = (ActivatableRef) handler.getRef();
                    } else {
                        throw new RuntimeException("unknown proxy type");
                    }

                    final ActivatableRef ref = aref;
                    Field f = (Field)
                        java.security.AccessController.doPrivileged
                        (new java.security.PrivilegedExceptionAction() {
                            public Object run() throws Exception {
                                Field ff = ref.getClass().getDeclaredField("ref");
                                ff.setAccessible(true);
                                return ff;
                            }
                        });
                    Object insideRef = f.get(ref);
                    System.err.println("insideRef = " + insideRef);
                    if (insideRef instanceof ActivatableRef) {
                        TestLibrary.bomb("Embedded ref is an ActivatableRef");
                    } else {
                        System.err.println("ActivatableRef's embedded ref type: " +
                                           insideRef.getClass().getName());
                    }

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

                    try {
                        // give activation group time to go away
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                    }
                }
            } catch (java.rmi.UnmarshalException ue) {
                // account for test's activation race condition
                if (ue.detail instanceof java.io.IOException) {
                    if ((failures ++) >= 3) {
                        throw ue;
                    }
                } else {
                    throw ue;
                }
            }

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

        } catch (java.rmi.activation.ActivationException e) {
            // test only needs to pass 3 times in 7
            if (i < 4) {
                TestLibrary.bomb(e);
            }
        } catch (Exception e) {
            if (e instanceof java.security.PrivilegedActionException)
                e = ((java.security.PrivilegedActionException)e).getException();
            TestLibrary.bomb("\nfailure: unexpected exception " +
                             e.getClass().getName(), e);

        } finally {
            ActivationLibrary.rmidCleanup(rmid);
            obj = null;
        }
    }
}
