Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java
38855 views
/*1* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 409489125* @summary unable to retry call if cached connection to server is used26* @library ../../../../java/rmi/testlibrary27* @build TestLibrary JavaVM28* @run main/othervm DeadCachedConnection29*/3031/* Fault: Cached connections used for remote invocations exhibited32* failure (sudden EOF or a TCP-related exception) immediately on33* sending a new request. It was then impossible to tell whether the34* connection had managed to transport the request before dying; even35* deserialization of request arguments is non-idempotent in general.36*37* In fact, this problem cannot be solved generally without rewriting38* the protocol. For now, the common case is the closing of an idle39* connection by a loaded/bored/dead server host.40*41* The fix is/was to trivially attempt to execute a non-blocking read42* on the connection before reusing it, to see if an exception/EOF is43* waiting for delivery. This is a 99%/1% solution, but until the44* great protocol rewrite, it's the best option.45*46* Reproducing is by establishing a connection to a registry and47* killing/restarting that registry (this forces the TCP connection48* to close). The next call to the registry will use the (stale)49* cached connection, and will fail without the bugfix.50*/5152import java.io.*;53import java.rmi.*;54import java.rmi.registry.*;55import java.rmi.server.*;5657public class DeadCachedConnection {58static public final int regport = TestLibrary.getUnusedRandomPort();5960static public void main(String[] argv)61throws Exception {62// establish the registry (we hope)63System.err.println ("Starting registry on port " + regport);64DeadCachedConnection.makeRegistry(regport);6566// Get a handle to the registry67Registry reg = null;68System.err.println ("Locating just-started registry...");69try {70reg = LocateRegistry.getRegistry(regport);71} catch (RemoteException e) {72throw new InternalError ("Can't find registry after starting it.");73}7475// Contact the registry by invoking something on it.76System.err.println ("Connecting to registry...");77String[] junk = reg.list();7879// Kill and restart the registry80System.err.println("Killing registry...");81DeadCachedConnection.killRegistry();82System.err.println("Restarting registry...");83DeadCachedConnection.makeRegistry(regport);8485// Try again (this is the test)86System.err.println("Trying to use registry in spite of stale cache...");87junk = reg.list();8889// we're happy90System.err.println("Test succeeded.");91try {92DeadCachedConnection.killRegistry();93} catch (Exception foo) {94}95}9697public static void makeRegistry(int p) {98// sadly, we can't kill a registry if we have too-close control99// over it. We must make it in a subprocess, and then kill the100// subprocess when it has served our needs.101102try {103JavaVM jvm =104new JavaVM("sun.rmi.registry.RegistryImpl", "", Integer.toString(p));105jvm.start();106DeadCachedConnection.subreg = jvm;107108} catch (IOException e) {109// one of these is summarily dropped, can't remember which one110System.out.println ("Test setup failed - cannot run rmiregistry");111TestLibrary.bomb("Test setup failed - cannot run test", e);112}113// Slop - wait for registry to come up. This is stupid.114try {115Thread.sleep (5000);116} catch (Exception whatever) {117}118}119private static JavaVM subreg = null;120121public static void killRegistry() {122if (DeadCachedConnection.subreg != null) {123DeadCachedConnection.subreg.destroy();124try { Thread.sleep(2000); } catch (InterruptedException ie) {}125}126DeadCachedConnection.subreg = null;127}128}129130131