/** * 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. * * <p>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 instanceof SocketChannel) { throw new IllegalArgumentException("got a Socket Channel instead"); } 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(); } }