Path: blob/master/test/jdk/sun/rmi/transport/tcp/DeadCachedConnection.java
41153 views
/*1* Copyright (c) 1998, 2017, 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 4094891 815777725* @summary unable to retry call if cached connection to server is used26* @library ../../../../java/rmi/testlibrary27* @modules java.rmi/sun.rmi.registry28* java.rmi/sun.rmi.server29* java.rmi/sun.rmi.transport30* java.rmi/sun.rmi.transport.tcp31* @build TestLibrary RegistryVM RegistryRunner32* @run main/othervm DeadCachedConnection33*/3435/* Fault: Cached connections used for remote invocations exhibited36* failure (sudden EOF or a TCP-related exception) immediately on37* sending a new request. It was then impossible to tell whether the38* connection had managed to transport the request before dying; even39* deserialization of request arguments is non-idempotent in general.40*41* In fact, this problem cannot be solved generally without rewriting42* the protocol. For now, the common case is the closing of an idle43* connection by a loaded/bored/dead server host.44*45* The fix is/was to trivially attempt to execute a non-blocking read46* on the connection before reusing it, to see if an exception/EOF is47* waiting for delivery. This is a 99%/1% solution, but until the48* great protocol rewrite, it's the best option.49*50* Reproducing is by establishing a connection to a registry and51* killing/restarting that registry (this forces the TCP connection52* to close). The next call to the registry will use the (stale)53* cached connection, and will fail without the bugfix.54*/5556import java.io.*;57import java.rmi.*;58import java.rmi.registry.*;59import java.rmi.server.*;6061public class DeadCachedConnection {6263static public void main(String[] argv)64throws Exception {65try {66Registry reg = null;67int port = makeRegistry(0);6869// Get a handle to the registry70System.err.println ("Locating just-started registry...");71try {72reg = LocateRegistry.getRegistry(port);73} catch (RemoteException e) {74throw new InternalError ("Can't find registry after starting it.");75}7677// Contact the registry by invoking something on it.78System.err.println ("Connecting to registry...");79String[] junk = reg.list();8081// Kill and restart the registry82System.err.println("Killing registry...");83killRegistry();84System.err.println("Restarting registry...");85makeRegistry(port);8687// Try again (this is the test)88System.err.println("Trying to use registry in spite of stale cache...");89junk = reg.list();9091System.err.println("Test succeeded.");92} catch (Exception e) {93TestLibrary.bomb(e);94} finally {95// dont leave the registry around to affect other tests.96killRegistry();97}98}99100public static int makeRegistry(int port) {101try {102subreg = RegistryVM.createRegistryVM(System.out, System.err, "", port);103subreg.start();104int regPort = subreg.getPort();105System.out.println("Starting registry on port " + regPort);106return regPort;107} catch (IOException e) {108// one of these is summarily dropped, can't remember which one109System.out.println ("Test setup failed - cannot run rmiregistry");110TestLibrary.bomb("Test setup failed - cannot run test", e);111}112return -1;113}114115private static RegistryVM subreg = null;116117public static void killRegistry() throws InterruptedException {118if (subreg != null) {119subreg.cleanup();120subreg = null;121}122}123}124125126