/*
 * Copyright (c) 1996, 2016, 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
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package java.rmi.server;

import java.io.*;
import java.net.*;

An RMISocketFactory instance is used by the RMI runtime in order to obtain client and server sockets for RMI calls. An application may use the setSocketFactory method to request that the RMI runtime use its socket factory instance instead of the default implementation.

The default socket factory implementation creates a direct socket connection to the remote host.

The default socket factory implementation creates server sockets that are bound to the wildcard address, which accepts requests from all network interfaces.

Author: Ann Wollrath, Peter Jones
Implementation Note:

You can use the RMISocketFactory class to create a server socket that is bound to a specific address, restricting the origin of requests. For example, the following code implements a socket factory that binds server sockets to an IPv4 loopback address. This restricts RMI to processing requests only from the local host.


    class LoopbackSocketFactory extends RMISocketFactory {
        public ServerSocket createServerSocket(int port) throws IOException {
            return new ServerSocket(port, 5, InetAddress.getByName("127.0.0.1"));
        }
        public Socket createSocket(String host, int port) throws IOException {
            // just call the default client socket factory
            return RMISocketFactory.getDefaultSocketFactory()
                                   .createSocket(host, port);
        }
    }
    // ...
    RMISocketFactory.setSocketFactory(new LoopbackSocketFactory());
Set the java.rmi.server.hostname system property to 127.0.0.1 to ensure that the generated stubs connect to the right network interface.
Since: 1.1
/** * An <code>RMISocketFactory</code> instance is used by the RMI runtime * in order to obtain client and server sockets for RMI calls. An * application may use the <code>setSocketFactory</code> method to * request that the RMI runtime use its socket factory instance * instead of the default implementation. * * <p>The default socket factory implementation creates a direct * socket connection to the remote host. * * <p>The default socket factory implementation creates server sockets that * are bound to the wildcard address, which accepts requests from all network * interfaces. * * @implNote * <p>You can use the {@code RMISocketFactory} class to create a server socket that * is bound to a specific address, restricting the origin of requests. For example, * the following code implements a socket factory that binds server sockets to an IPv4 * loopback address. This restricts RMI to processing requests only from the local host. * * <pre>{@code * class LoopbackSocketFactory extends RMISocketFactory { * public ServerSocket createServerSocket(int port) throws IOException { * return new ServerSocket(port, 5, InetAddress.getByName("127.0.0.1")); * } * * public Socket createSocket(String host, int port) throws IOException { * // just call the default client socket factory * return RMISocketFactory.getDefaultSocketFactory() * .createSocket(host, port); * } * } * * // ... * * RMISocketFactory.setSocketFactory(new LoopbackSocketFactory()); * }</pre> * * Set the {@code java.rmi.server.hostname} system property * to {@code 127.0.0.1} to ensure that the generated stubs connect to the right * network interface. * * @author Ann Wollrath * @author Peter Jones * @since 1.1 */
public abstract class RMISocketFactory implements RMIClientSocketFactory, RMIServerSocketFactory {
Client/server socket factory to be used by RMI runtime
/** Client/server socket factory to be used by RMI runtime */
private static RMISocketFactory factory = null;
default socket factory used by this RMI implementation
/** default socket factory used by this RMI implementation */
private static RMISocketFactory defaultSocketFactory;
Handler for socket creation failure
/** Handler for socket creation failure */
private static RMIFailureHandler handler = null;
Constructs an RMISocketFactory.
Since:1.1
/** * Constructs an <code>RMISocketFactory</code>. * @since 1.1 */
public RMISocketFactory() { super(); }
Creates a client socket connected to the specified host and port.
Params:
  • host – the host name
  • port – the port number
Throws:
  • IOException – if an I/O error occurs during socket creation
Returns:a socket connected to the specified host and port.
Since:1.1
/** * Creates a client socket connected to the specified host and port. * @param host the host name * @param port the port number * @return a socket connected to the specified host and port. * @exception IOException if an I/O error occurs during socket creation * @since 1.1 */
public abstract Socket createSocket(String host, int port) throws IOException;
Create a server socket on the specified port (port 0 indicates an anonymous port).
Params:
  • port – the port number
Throws:
  • IOException – if an I/O error occurs during server socket creation
Returns:the server socket on the specified port
Since:1.1
/** * Create a server socket on the specified port (port 0 indicates * an anonymous port). * @param port the port number * @return the server socket on the specified port * @exception IOException if an I/O error occurs during server socket * creation * @since 1.1 */
public abstract ServerSocket createServerSocket(int port) throws IOException;
Set the global socket factory from which RMI gets sockets (if the remote object is not associated with a specific client and/or server socket factory). The RMI socket factory can only be set once. Note: The RMISocketFactory may only be set if the current security manager allows setting a socket factory; if disallowed, a SecurityException will be thrown.
Params:
  • fac – the socket factory
Throws:
  • IOException – if the RMI socket factory is already set
  • SecurityException – if a security manager exists and its checkSetFactory method doesn't allow the operation.
See Also:
Since:1.1
/** * Set the global socket factory from which RMI gets sockets (if the * remote object is not associated with a specific client and/or server * socket factory). The RMI socket factory can only be set once. Note: The * RMISocketFactory may only be set if the current security manager allows * setting a socket factory; if disallowed, a SecurityException will be * thrown. * @param fac the socket factory * @exception IOException if the RMI socket factory is already set * @exception SecurityException if a security manager exists and its * <code>checkSetFactory</code> method doesn't allow the operation. * @see #getSocketFactory * @see java.lang.SecurityManager#checkSetFactory() * @since 1.1 */
public synchronized static void setSocketFactory(RMISocketFactory fac) throws IOException { if (factory != null) { throw new SocketException("factory already defined"); } SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkSetFactory(); } factory = fac; }
Returns the socket factory set by the setSocketFactory method. Returns null if no socket factory has been set.
See Also:
Returns:the socket factory
Since:1.1
/** * Returns the socket factory set by the <code>setSocketFactory</code> * method. Returns <code>null</code> if no socket factory has been * set. * @return the socket factory * @see #setSocketFactory(RMISocketFactory) * @since 1.1 */
public synchronized static RMISocketFactory getSocketFactory() { return factory; }
Returns a reference to the default socket factory used by this RMI implementation. This will be the factory used by the RMI runtime when getSocketFactory returns null.
Returns:the default RMI socket factory
Since:1.1
/** * Returns a reference to the default socket factory used * by this RMI implementation. This will be the factory used * by the RMI runtime when <code>getSocketFactory</code> * returns <code>null</code>. * @return the default RMI socket factory * @since 1.1 */
public synchronized static RMISocketFactory getDefaultSocketFactory() { if (defaultSocketFactory == null) { defaultSocketFactory = new sun.rmi.transport.tcp.TCPDirectSocketFactory(); } return defaultSocketFactory; }
Sets the failure handler to be called by the RMI runtime if server socket creation fails. By default, if no failure handler is installed and server socket creation fails, the RMI runtime does attempt to recreate the server socket.

If there is a security manager, this method first calls the security manager's checkSetFactory method to ensure the operation is allowed. This could result in a SecurityException.

Params:
  • fh – the failure handler
Throws:
  • SecurityException – if a security manager exists and its checkSetFactory method doesn't allow the operation.
See Also:
Since:1.1
/** * Sets the failure handler to be called by the RMI runtime if server * socket creation fails. By default, if no failure handler is installed * and server socket creation fails, the RMI runtime does attempt to * recreate the server socket. * * <p>If there is a security manager, this method first calls * the security manager's <code>checkSetFactory</code> method * to ensure the operation is allowed. * This could result in a <code>SecurityException</code>. * * @param fh the failure handler * @throws SecurityException if a security manager exists and its * <code>checkSetFactory</code> method doesn't allow the * operation. * @see #getFailureHandler * @see java.rmi.server.RMIFailureHandler#failure(Exception) * @since 1.1 */
public synchronized static void setFailureHandler(RMIFailureHandler fh) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkSetFactory(); } handler = fh; }
Returns the handler for socket creation failure set by the setFailureHandler method.
See Also:
Returns:the failure handler
Since:1.1
/** * Returns the handler for socket creation failure set by the * <code>setFailureHandler</code> method. * @return the failure handler * @see #setFailureHandler(RMIFailureHandler) * @since 1.1 */
public synchronized static RMIFailureHandler getFailureHandler() { return handler; } }