--- old/test/java/rmi/testlibrary/TestLibrary.java 2012-07-13 13:17:30.326764208 -0700 +++ new/test/java/rmi/testlibrary/TestLibrary.java 2012-07-13 13:17:30.122760960 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012, 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 @@ -36,37 +36,63 @@ * not make use of packages. */ +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.io.OutputStream; import java.io.PrintStream; -import java.net.URL; import java.net.MalformedURLException; -import java.rmi.activation.Activatable; -import java.rmi.activation.ActivationID; +import java.net.ServerSocket; +import java.net.URL; import java.rmi.NoSuchObjectException; -import java.rmi.registry.Registry; import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.rmi.server.ExportException; +import java.rmi.server.RemoteRef; import java.rmi.server.UnicastRemoteObject; import java.util.Enumeration; -import java.util.Hashtable; import java.util.Properties; -import java.io.ByteArrayOutputStream; -import java.security.AccessController; -import java.security.PrivilegedAction; +import sun.rmi.registry.RegistryImpl; +import sun.rmi.server.UnicastServerRef; +import sun.rmi.transport.Endpoint; +import sun.rmi.transport.LiveRef; +import sun.rmi.transport.tcp.TCPEndpoint; /** * Class of utility/library methods (i.e. procedures) that assist with * the writing and maintainance of rmi regression tests. */ public class TestLibrary { - - /** standard test port number for registry */ - public final static int REGISTRY_PORT = 2006; - /** port for rmid necessary: not used to actually start rmid */ - public final static int RMID_PORT = 1098; + /** + * IMPORTANT! + * + * RMI tests are run concurrently and port conflicts result when a single + * port number is used by multiple tests. When needing a port, use + * getUnusedRandomPort() wherever possible. If getUnusedRandomPort() cannot + * be used, reserve and specify a port to use for your test here. This + * will ensure there are no port conflicts amongst the RMI tests. The + * port numbers specified here may also be specified in the respective + * tests. Do not change the reserved port numbers here without also + * changing the port numbers in the respective tests. + * + * When needing an instance of the RMIRegistry, use + * createRegistryOnUnusedPort wherever possible to prevent port conflicts. + * + * Reserved port range: FIXED_PORT_MIN to FIXED_PORT_MAX (inclusive) for + * tests which cannot use a random port. If new fixed ports are added below + * FIXED_PORT_MIN or above FIXED_PORT_MAX, then adjust + * FIXED_PORT_MIN/MAX appropriately. + */ + public final static int FIXED_PORT_MIN = 64001; + public final static int FIXED_PORT_MAX = 64010; + public final static int RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT = 64001; + public final static int RMIDVIAINHERITEDCHANNEL_REGISTRY_PORT = 64002; + public final static int INHERITEDCHANNELNOTSERVERSOCKET_ACTIVATION_PORT = 64003; + public final static int INHERITEDCHANNELNOTSERVERSOCKET_REGISTRY_PORT = 64004; + public final static int READTEST_REGISTRY_PORT = 64005; static void mesg(Object mesg) { System.err.println("TEST_LIBRARY: " + mesg.toString()); @@ -340,6 +366,92 @@ } /** + * Creates an RMI {@link Registry} on a random port. + * + * @returns an RMI Registry, using a random port. + * @throws RemoteException if there was a problem creating a Registry. + */ + public static Registry createRegistryOnUnusedPort() throws RemoteException { + Registry registry = null; + + try { + registry = LocateRegistry.createRegistry(0); + } catch (ExportException ee) { + // If we have an ExportException, it's becuase there's already a + // registry which was created using + // LocateRegistry.createRegistry(0) running in this VM. Try + // getting a random port and creating the registry using the + // random port instead. + int port = getUnusedRandomPort(); + + try { + registry = LocateRegistry.createRegistry(port); + } catch(RemoteException re) { + throw new RemoteException("Could not create registry."); + } + } catch (Exception ex) { + throw new RemoteException("Could not create registry."); + } + + return registry; + } + + /** + * Returns the port number the RMI {@link Registry} is running on. + * + * @param registry the registry to find the port of. + * @return the port number the registry is using. + * @throws NullPointerException if registry is {@code null}. + * @throws RuntimeException if there was a problem getting the port number. + */ + public static int getRegistryPort(Registry registry) { + int port = -1; + + try { + RemoteRef remoteRef = ((RegistryImpl)registry).getRef(); + LiveRef liveRef = ((UnicastServerRef)remoteRef).getLiveRef(); + Endpoint endpoint = liveRef.getChannel().getEndpoint(); + TCPEndpoint tcpEndpoint = (TCPEndpoint) endpoint; + port = tcpEndpoint.getPort(); + } catch (Exception ex) { + throw new RuntimeException("Error getting registry port."); + } + + return port; + } + + /** + * Returns an unused random port number less than FIXED_PORT_MIN and greater + * than FIXED_PORT_MAX. Will try up to 10 times to get a random port before + * giving up and throwing a RuntimeException. + * + * @return an unused random port number. + * @throws RuntimeException if there was a problem getting a port. + */ + public static int getUnusedRandomPort() { + int numTries = 0; + int unusedRandomPort = FIXED_PORT_MIN; + + while ((numTries++ < 10) && ((unusedRandomPort >= FIXED_PORT_MIN) && + (unusedRandomPort <= FIXED_PORT_MAX))) + { + try (ServerSocket ss = new ServerSocket(0)) { + unusedRandomPort = ss.getLocalPort(); + } catch (Exception e) { + // Do nothing + } + } + + if ((unusedRandomPort >= FIXED_PORT_MIN) && + (unusedRandomPort <= FIXED_PORT_MAX)) + { + throw new RuntimeException("Error getting unused random port."); + } + + return unusedRandomPort; + } + + /** * Method to capture the stack trace of an exception and return it * as a string. */