8188897: java/rmi/registry/reexport/Reexport.java failed with Port already in use

Reviewed-by: rriggs, darcy
This commit is contained in:
Hamlin Li 2018-04-11 09:08:43 +08:00
parent e371d95422
commit 6b2da27d9a

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. 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
@ -29,79 +29,70 @@
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
* @build TestLibrary RegistryVM RegistryRunner
* @build TestLibrary
* @run main/othervm Reexport
*/
/*
* If a VM could not create an RMI registry because another registry
* usually in another process, was using the registry port, the next
* If a VM could not create an RMI registry because the registry port
* was already occupied by this or other processes, the next
* time the VM tried to create a registry (after the other registry
* was brought down) the attempt would fail. The second try to create
* a registry would fail because the registry ObjID would still be in
* use when it should never have been allocated.
*
* The test creates this conflict using Runtime.exec and ensures that
* a registry can still be created after the conflict is resolved.
* The test creates this conflict starting a dummy tcp server and ensures
* that a registry can still be created after the conflict is resolved.
*/
import java.io.*;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Reexport {
static public void main(String[] argv) {
static public void main(String[] argv) throws IOException {
Registry reg = null;
try {
System.err.println("\nregression test for 4120329\n");
for (int loop = 0; loop < 10; loop++) {
System.err.println("\nat loop: " + loop);
int port = -1;
try (ServerSocketChannel server = ServerSocketChannel.open();) {
server.bind(null);
InetSocketAddress addr = (InetSocketAddress)server.getLocalAddress();
port = addr.getPort();
// establish the registry (we hope)
makeRegistry();
// Get a handle to the registry
System.err.println("Creating duplicate registry, this should fail...");
reg = createReg(true);
// Kill the first registry.
System.err.println("Bringing down the first registry");
System.err.println("Creating duplicate registry, this should fail...");
createReg(port, true);
}
try {
killRegistry();
} catch (Exception foo) {
if (createReg(port, false) == null) {
TestLibrary.bomb("Could not create registry on second try");
}
System.err.println("Test passed");
return;
} catch (Exception e) {
String err = e.getMessage();
if (err.contains("Address already in use")
|| err.contains("Port already in use")) {
continue;
}
TestLibrary.bomb(e);
}
// start another registry now that the first is gone; this should work
System.err.println("Trying again to start our own " +
"registry... this should work");
reg = createReg(false);
if (reg == null) {
TestLibrary.bomb("Could not create registry on second try");
}
System.err.println("Test passed");
} catch (Exception e) {
TestLibrary.bomb(e);
} finally {
// dont leave the registry around to affect other tests.
killRegistry();
reg = null;
}
TestLibrary.bomb("Test failed");
}
static Registry createReg(boolean remoteOk) {
static Registry createReg(int port, boolean expectException) {
Registry reg = null;
try {
reg = LocateRegistry.createRegistry(port);
if (remoteOk) {
TestLibrary.bomb("Remote registry is up, an Exception is expected!");
if (expectException) {
TestLibrary.bomb("Registry is up, an Exception is expected!");
}
} catch (Throwable e) {
if (remoteOk) {
if (expectException) {
System.err.println("EXPECTING PORT IN USE EXCEPTION:");
System.err.println(e.getMessage());
e.printStackTrace();
@ -111,27 +102,4 @@ public class Reexport {
}
return reg;
}
public static void makeRegistry() {
try {
subreg = RegistryVM.createRegistryVM();
subreg.start();
port = subreg.getPort();
System.out.println("Starting registry on port " + port);
} 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);
}
}
private static RegistryVM subreg = null;
private static int port = -1;
public static void killRegistry() {
if (subreg != null) {
subreg.cleanup();
subreg = null;
}
}
}