📄 initializeregistry.java
字号:
/* * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * -Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF * THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that Software is not designed, licensed or * intended for use in the design, construction, operation or * maintenance of any nuclear facility. */package example.inetd;import java.io.IOException;import java.io.InterruptedIOException;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;import java.net.SocketAddress;import java.net.SocketException;import java.nio.channels.Channel;import java.nio.channels.ServerSocketChannel;import java.rmi.AlreadyBoundException;import java.rmi.Remote;import java.rmi.RemoteException;import java.rmi.registry.LocateRegistry;import java.rmi.registry.Registry;import java.rmi.server.RMIServerSocketFactory;/** * A utility to export a registry (using an inherited channel if launched * from <code>inetd</code>) and to bind a remote service's proxy in that * registry for clients to look up. **/public class InitializeRegistry { private static final Object lock = new Object(); private static boolean serviceAvailable = false; private static boolean initialized = false; /** * Prevents instantiation. */ private InitializeRegistry() { throw new AssertionError(); } /** * Creates and exports a registry (using an inherited channel, if any, * as specified below), and binds the specified name to the specified * proxy in that registry. * * First, the registry is exported as follows: * <ul> * <li>If the <code>System.inheritedChannel</code> method returns a * <code>ServerSocketChannel</code> instance, the registry is exported * with an <code>RMIServerSocketFactory</code> whose * <code>createServerSocket</code> method returns a * <code>ServerSocket</code> for the inherited * <code>ServerSocketChannel</code> that delays accepting * requests until the specified proxy is bound in the * registry. * * <li>If the <code>System.inheritedChannel</code> method returns * <code>null</code>, then the registry is exported with an * <code>RMIServerSocketFactory</code> whose * <code>createServerSocket</code> method returns a * <code>ServerSocket</code> constructed with the specified * port that delays accepting requests until the specified proxy is * bound in the registry. In this case, if the port is <code>0</code>, * then an <code>IllegalArgumentException</code> is thrown. * * <li>Otherwise, if the <code>System.inheritedChannel</code> returns * an instance of any other type, an <code>IOException</code> is * thrown. * </ul> * * <p>Once the registry is exported, the registry's <code>bind</code> * method is invoked with the specified name and proxy as arguments. * * @param obj the proxy for a remote object * @param name the name for the remote object in the registry * @param port a port to export the registry on if there is no * inherited channel * @throws IllegalArgumentException if the inherited channel is * <code>null</code> and the port is <code>0</code> * @throws IllegalStateException if this method was called previously * @throws IOException if the inherited channel is not an instance * of <code>ServerSocketChannel</code> or <code>null</code> * @throws RemoteException if the registry could not be exported **/ public static void initializeWithInheritedChannel(Remote proxy, String name, int port) throws IOException { /* * Only allow this method to be invoked once. */ synchronized (InitializeRegistry.class) { if (initialized) { throw new IllegalStateException("already invoked"); } initialized = true; } Channel channel = System.inheritedChannel(); ServerSocket serverSocket = null; /* * Handle inherited channel, if any. */ if (channel instanceof ServerSocketChannel) { /* * Service launched from inetd. Get server socket from * inherited server socket channel. */ serverSocket = ((ServerSocketChannel) channel).socket(); } else if (channel == null) { /* * Service launched from the command line. In this case, the * port specified for the registry must be nonzero */ if (port == 0) { throw new IllegalArgumentException("port must be nonzero"); } serverSocket = new ServerSocket(port); } else { throw new IOException( "unexpected channel returned from inheritedChannel: " + channel.toString()); } /* * Create server socket factory for registry to delay accepting * calls until a service is bound in the registry. */ RMIServerSocketFactory ssf = new RegistryServerSocketFactory(serverSocket); /* * Create/export registry and bind name to proxy in registry. */ Registry registry = LocateRegistry.createRegistry(port, null, ssf); try { registry.bind(name, proxy); } catch (RemoteException impossible) { throw new AssertionError(impossible); } catch (AlreadyBoundException impossible) { throw new AssertionError(impossible); } /* * Notify registry's socket factory that the service proxy is * bound in the registry, so that the registry can accept * incoming requests to look up the service. */ synchronized (lock) { serviceAvailable = true; lock.notifyAll(); } } /** * A server socket factory to use when exporting a registry launched * from 'inetd' with 'wait' status. This socket factory's * 'createServerSocket' method returns a server socket that wraps the * server socket specified during construction and is specialized to * delay accepting requests until a remote service is bound in the * registry (when the 'serviceAvailable' flag is 'true'). The server * socket supplied to the constructor should be the server socket * obtained from the 'System.inheritedChannel' method. * * Note that only a single instance of this class should be created. **/ private static class RegistryServerSocketFactory implements RMIServerSocketFactory { private final ServerSocket serverSocket; /** * Constructs a 'RegistryServerSocketFactory' with the specified * 'serverSocket'. **/ RegistryServerSocketFactory(ServerSocket serverSocket) { this.serverSocket = serverSocket; } /** * Returns the server socket specified during construction wrapped * in a 'DelayedAcceptServerSocket'. The port argument is ignored. **/ public ServerSocket createServerSocket(int port) throws IOException { return new DelayedAcceptServerSocket(serverSocket); } } /** * A server socket that delegates all public methods to the underlying * server socket specified at construction. The accept method is * overridden to delay calling accept on the underlying server socket * until a remote service is bound in the registry (when the * 'serviceAvailable' flag is 'true'). **/ private static class DelayedAcceptServerSocket extends ServerSocket { private final ServerSocket serverSocket; /** * Constructs a 'DelayedAcceptServerSocket' with the specified * 'serverSocket'. */ DelayedAcceptServerSocket(ServerSocket serverSocket) throws IOException { this.serverSocket = serverSocket; } public void bind(SocketAddress endpoint) throws IOException { serverSocket.bind(endpoint); } public void bind(SocketAddress endpoint, int backlog) throws IOException { serverSocket.bind(endpoint, backlog); } public InetAddress getInetAddress() { return serverSocket.getInetAddress(); } public int getLocalPort() { return serverSocket.getLocalPort(); } public SocketAddress getLocalSocketAddress() { return serverSocket.getLocalSocketAddress(); } /** * Delays calling accept on the underlying server socket until the * remote service is bound in the registry. **/ public Socket accept() throws IOException { synchronized (lock) { try { while (!serviceAvailable) { lock.wait(); } } catch (InterruptedException e) { throw (IOException) (new InterruptedIOException()).initCause(e); } } return serverSocket.accept(); } public void close() throws IOException { serverSocket.close(); } public ServerSocketChannel getChannel() { return serverSocket.getChannel(); } public boolean isBound() { return serverSocket.isBound(); } public boolean isClosed() { return serverSocket.isClosed(); } public void setSoTimeout(int timeout) throws SocketException { serverSocket.setSoTimeout(timeout); } public int getSoTimeout() throws IOException { return serverSocket.getSoTimeout(); } public void setReuseAddress(boolean on) throws SocketException { serverSocket.setReuseAddress(on); } public boolean getReuseAddress() throws SocketException { return serverSocket.getReuseAddress(); } public String toString() { return serverSocket.toString(); } public void setReceiveBufferSize(int size) throws SocketException { serverSocket.setReceiveBufferSize(size); } public int getReceiveBufferSize() throws SocketException { return serverSocket.getReceiveBufferSize(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -