/*
 * Copyright 1998-2004 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 4094891
 * @summary unable to retry call if cached connection to server is used
 * @library ../../../../java/rmi/testlibrary
 * @build DeadCachedConnection
 * @build JavaVM
 * @build TestLibrary
 * @run main/othervm DeadCachedConnection
 */

/* Fault: Cached connections used for remote invocations exhibited
 * failure (sudden EOF or a TCP-related exception) immediately on
 * sending a new request.  It was then impossible to tell whether the
 * connection had managed to transport the request before dying; even
 * deserialization of request arguments is non-idempotent in general.
 *
 * In fact, this problem cannot be solved generally without rewriting
 * the protocol.  For now, the common case is the closing of an idle
 * connection by a loaded/bored/dead server host.
 *
 * The fix is/was to trivially attempt to execute a non-blocking read
 * on the connection before reusing it, to see if an exception/EOF is
 * waiting for delivery.  This is a 99%/1% solution, but until the
 * great protocol rewrite, it's the best option.
 *
 * Reproducing is by establishing a connection to a registry and
 * killing/restarting that registry (this forces the TCP connection
 * to close).  The next call to the registry will use the (stale)
 * cached connection, and will fail without the bugfix.
 */

import java.io.*;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;

public class DeadCachedConnection {
    static public final int regport = 17340;

    static public void main(String[] argv)
        throws Exception {
        // establish the registry (we hope)
        System.err.println ("Starting registry on port " + regport);
        DeadCachedConnection.makeRegistry(regport);

        // Get a handle to the registry
        Registry reg = null;
        System.err.println ("Locating just-started registry...");
        try {
            reg = LocateRegistry.getRegistry(regport);
        } catch (RemoteException e) {
            throw new InternalError ("Can't find registry after starting it.");
        }

        // Contact the registry by invoking something on it.
        System.err.println ("Connecting to registry...");
        String[] junk = reg.list();

        // Kill and restart the registry
        System.err.println("Killing registry...");
        DeadCachedConnection.killRegistry();
        System.err.println("Restarting registry...");
        DeadCachedConnection.makeRegistry(regport);

        // Try again (this is the test)
        System.err.println("Trying to use registry in spite of stale cache...");
        junk = reg.list();

        // we're happy
        System.err.println("Test succeeded.");
        try {
            DeadCachedConnection.killRegistry();
        } catch (Exception foo) {
        }
    }

    public static void makeRegistry(int p) {
        // sadly, we can't kill a registry if we have too-close control
        // over it.  We must make it in a subprocess, and then kill the
        // subprocess when it has served our needs.

        try {
            JavaVM jvm =
                new JavaVM("sun.rmi.registry.RegistryImpl", "", Integer.toString(p));
            jvm.start();
            DeadCachedConnection.subreg = jvm.getVM();

        } catch (IOException e) {
            // one of these is summarily dropped, can't remember which one
            System.out.println ("Test setup failed - cannot run rmiregistry");
            TestLibrary.bomb("Test setup failed - cannot run test", e);
        }
        // Slop - wait for registry to come up.  This is stupid.
        try {
            Thread.sleep (5000);
        } catch (Exception whatever) {
        }
    }
    private static Process subreg = null;

    public static void killRegistry() {
        if (DeadCachedConnection.subreg != null) {
            DeadCachedConnection.subreg.destroy();
            try { Thread.sleep(2000); } catch (InterruptedException ie) {}
        }
        DeadCachedConnection.subreg = null;
    }
}
