Path: blob/master/test/jdk/java/rmi/testlibrary/RegistryRunner.java
41149 views
/*1* Copyright (c) 1999, 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/**/2425import java.rmi.*;26import java.rmi.registry.*;27import java.rmi.server.*;2829/**30* Class to run a registry whose VM can be told to exit remotely; using31* a registry (in a sub-process) in this fashion makes tests more robust under32* windows where Process.destroy() seems not to be 100% reliable.33*/34public class RegistryRunner extends UnicastRemoteObject35implements RemoteExiter36{37private static final String PORT_LABEL_START = "RegistryRunner.port.start:";38private static final String PORT_LABEL_END = ":RegistryRunner.port.end";3940protected static Registry registry = null;41protected static RemoteExiter exiter = null;4243public RegistryRunner() throws RemoteException {44}4546/**47* Ask the registry to exit instead of forcing it do so; this48* works better on windows...49*/50public void exit() throws RemoteException {51// REMIND: create a thread to do this to avoid52// a remote exception?53System.err.println("received call to exit");54System.exit(0);55}5657/**58* Request that the registry process exit and handle59* related exceptions.60*/61public static void requestExit(int port) {6263try {64RemoteExiter e =65(RemoteExiter)66Naming.lookup("rmi://localhost:" +67port +68"/RemoteExiter");69try {70e.exit();71} catch (RemoteException re) {72}73e = null;7475} catch (java.net.MalformedURLException mfue) {76// will not happen77} catch (NotBoundException nbe) {78TestLibrary.bomb("exiter not bound?", nbe);79} catch (RemoteException re) {80TestLibrary.bomb("remote exception trying to exit",81re);82}83}8485public static int getRegistryPort(String output) {86int idxStart = output.indexOf(PORT_LABEL_START);87int idxEnd = output.indexOf(PORT_LABEL_END);88if (idxStart == -1 || idxEnd == -1) {89return -1;90}91idxStart = idxStart+PORT_LABEL_START.length();92String portStr = output.substring(idxStart, idxEnd);93int port = Integer.valueOf(portStr);94System.err.println("registry is running at port: " + port);95return port;96}9798/**99* port 0 means to use ephemeral port to start registry.100*101* @param args command line arguments passed in from main102* @return the port number on which registry accepts requests103*/104protected static int init(String[] args) {105try {106if (args.length == 0) {107System.err.println("Usage: <port>");108System.exit(0);109}110int port = -1;111port = Integer.parseInt(args[0]);112113// create a registry114registry = LocateRegistry.createRegistry(port);115if (port == 0) {116port = TestLibrary.getRegistryPort(registry);117}118119// create a remote object to tell this VM to exit120exiter = new RegistryRunner();121Naming.rebind("rmi://localhost:" + port +122"/RemoteExiter", exiter);123124return port;125} catch (Exception e) {126System.err.println(e.getMessage());127e.printStackTrace();128System.exit(-1);129}130return -1;131}132133/**134* RegistryVM.start() will filter the output of registry subprocess,135* when valid port is detected, RegistryVM.start() returns.136* So, for subclass, it's important to call this method after registry137* is initialized and necessary remote objects have been bound.138*139* @param port the port on which registry accepts requests140*/141protected static void notify(int port) {142// this output is important for RegistryVM to get the port143// where rmiregistry is serving144System.out.println(PORT_LABEL_START + port + PORT_LABEL_END);145System.out.flush();146}147148public static void main(String[] args) {149int port = init(args);150notify(port);151}152}153154155