saker.build Documentation TaskDoc JavaDoc Packages
public class RMIServer implements AutoCloseable
Server class that is capable of accepting RMI connections on a given server socket.

This class can be used to open a server socket and listen for incoming connections on it. The connections will be appropriately handled using an internal protocol defined by this and the RMIConnection class.

Users can extend this class in order to specialize how the accepted connections should be handled.

The ServerSocketFactory class can be used to customize the server socket creation. This server class doesn't do any security checks whether the accepted connection should be allowed to use this server. Any security checks should be implemented by the subclasses.

The class is single use, meaning that after it has been started, it cannot be reset or restarted.

To ensure forward compatibility, when an RMI connection is established between a server and a client, the actual protocol version is negotiated between them. This is determined by taking the highest supported protocol version number by both parties. Users should keep this in mind, as the RMI runtime evolves, there might be features that is only available on one endpoint, therefore that feature will not be used during the connection.

Constructors
public
Creates a new server instance.
public
RMIServer(ServerSocketFactory socketfactory, int port, InetAddress bindaddress)
Creates a new server instance with the given arguments.
Methods
public final void
Starts the accepting of connections on this thread.
public final void
acceptConnections(ThreadGroup threadpoolthreadgroup)
Starts the accepting of connections on this thread.
public final void
Starts the accepting of connections on this thread.
public final void
Closes this RMI server and all associated RMI connections.
protected void
Requests the subclasses to release its resources.
public final void
Closes this RMI server and all associated RMI connections.
public final SocketAddress
Returns the address of the endpoint this server socket is bound to.
public final int
Returns the port number on which this socket is listening.
protected RMIOptions
getRMIOptionsForAcceptedConnection(Socket acceptedsocket, int protocolversion)
Gets the RMIOptions that should be used for the newly accepted RMI connection.
public static boolean
Pings the RMI server at the given address if there is any.
public static boolean
Pings the RMI server at the given address if there is any.
public static boolean
pingServer(SocketFactory socketfactory, SocketAddress address)
Pings the RMI server at the given address if there is any.
protected void
Called in case an exception is encountered during the operation of the RMIServer.
public final void
setConnectionTimeout(int connectionTimeout)
Sets the connection timeout for the accepted sockets.
protected void
setupConnection(Socket acceptedsocket, RMIConnection connection)
Sets up the accepted connection.
public static void
Sends a shutdown request to the RMI server running at the given address if any.
public static void
Sends a shutdown request to the RMI server running at the given address if any.
public static void
Sends a shutdown request to the RMI server running at the given address if any.
public final void
Starts the accepting of connections on a separate thread.
public final void
start(ThreadGroup threadpoolthreadgroup)
Starts the accepting of connections on a separate thread.
public final void
start(Executor executor)
Starts the accepting of connections on a given executor.
protected boolean
validateConnectionStream(Socket acceptedsocket, RMIConnection connection)
Checks if the newly accepted socket can be used to add a new stream to the argument RMI connection.
protected boolean
Checks if this server should respond to a ping request from the given socket successfully.
protected boolean
Checks if the RMI server can be shut down externally from the specified socket.
protected void
Called right after a client connection has been accepted.
public RMIServer() throws IOException
Creates a new server instance.

The default server socket factory, 0 port, and null bind address will be used.

IOExceptionIn case of I/O error.
public RMIServer(ServerSocketFactory socketfactory, int port, InetAddress bindaddress) throws IOException
Creates a new server instance with the given arguments.
socketfactoryThe server socket factory to use to create the server socket or null to use none.
portThe port number to listen for connections, or 0 to automatically allocate.
bindaddressThe local InetAddress the server will bind to.
IOExceptionIn case of I/O error.
public final void acceptConnections() throws IllegalStateException
Starts the accepting of connections on this thread.

This method is the same as calling acceptConnections(ThreadGroup) with null thread group.

IllegalStateExceptionIf the RMI server was already started previously.
public final void acceptConnections(ThreadGroup threadpoolthreadgroup) throws IllegalStateException
Starts the accepting of connections on this thread.

This method will execute the listening for connections on this thread, and therefore closing the RMI server will require external intervention.

This method will create a thread pool where the accepted connections will be handled. The argument thread group will be used as a parent thread group for the started threads in the thread pool. The threads in the thread pool are daemon threads, however users should not rely on this behaviour.

threadpoolthreadgroupThe thread group for the thread pool or null to use the current one.
IllegalStateExceptionIf the RMI server was already started previously.
Starts the accepting of connections on this thread.

This method will execute the listening for connections on this thread, and therefore closing the RMI server will require external intervention.

The newly accepted connections will be handled on the argument Executor.

executorThe executor to handle new connections on.
NullPointerExceptionIf the executor is null.
IllegalStateExceptionIf the RMI server was already started previously.
saker.rmi 0.8.3
public final void close() throws IOException
Closes this RMI server and all associated RMI connections.

This method closes the server in an asynchronous way. No more connections will be accepted, and the underlying resources are closed.

The still executing requests are not waited, therefore it is possible that some requests are still executing after this method returns. To wait for the concurrent requests to finish, call closeWait().

IOExceptionIn case of I/O error.
protected void closeImpl() throws IOException
Requests the subclasses to release its resources.

This method is called when the RMI server is being closed. This method is called after the underlying sockets have been closed, but before any RMI connections are closed.

Implementations shouldn't wait for any unrelated requests to finish in this method.

IOExceptionIn case of I/O error.
public final void closeWait() throws IOException, InterruptedException
Closes this RMI server and all associated RMI connections.

This method works the same way as close(), but will wait for any concurrent requests to finish.

IOExceptionIn case of I/O error.
InterruptedExceptionIf the current thread was interrupted.
Returns the address of the endpoint this server socket is bound to.
The socket address.
public final int getPort()
Returns the port number on which this socket is listening.

If this instance was constructed with 0 as port number, this will return the actual allocated port nonetheless.

The port number.
protected RMIOptions getRMIOptionsForAcceptedConnection(Socket acceptedsocket, int protocolversion) throws IOException, RuntimeException
Gets the RMIOptions that should be used for the newly accepted RMI connection.

This method is called by the server to determine the RMI options to use for the newly accepted connection.

If any exception is thrown by this method, the connection setup will be aborted, and it will be refused.

If implementations used an SSLSocketFactory or similar during instantiation of this server, they can use the argument socket to validate the identity of the client. Implementations will have a second chance for validating the socket in setupConnection(Socket, RMIConnection).

Implementations should not use the input and output streams of the accepted socket.

acceptedsocketThe accepted socket.
protocolversionThe negotiated protocol version of the connection.
The RMI options to use for the connection.
IOExceptionIn case of I/O error.
RuntimeExceptionIf the validation of the socket failed.
public static boolean pingServer(SocketAddress address) throws NullPointerException
Pings the RMI server at the given address if there is any.

Works the same way a pingServer(SocketFactory, SocketAddress) with null socket factory.

addressThe address to send the ping to.
true if the server was successfully pinged.
NullPointerExceptionIf the address is null.
public static boolean pingServer(SocketAddress address, RMISocketConfiguration socketconfig) throws NullPointerException
Pings the RMI server at the given address if there is any.

This method establishes a connection to the given address, and sends a ping request to the RMIServer running at that endpoint.

When the server receives the request, it will call its implementation validatePingRequest(Socket) method to check if it is allowed to respond to this request.

This method can be used to determine if there is an RMIServer running at the given address. If this method returns true, that can signal (but not always) that clients can connect and use that server.

This method doesn't throw IOException or others in case of errors, but will just simply return false.

addressThe address to send the ping to.
socketconfigThe socket configuration to use.
true if the server at the given address responded to the ping successfully.
NullPointerExceptionIf any of the arguments are null.
saker.rmi 0.8.2
public static boolean pingServer(SocketFactory socketfactory, SocketAddress address) throws NullPointerException
Pings the RMI server at the given address if there is any.

Works the same way as pingServer(SocketAddress, RMISocketConfiguration) with the given socket factory and defaults.

socketfactoryThe socket factory to use for connection, or null to use none.
addressThe address to send the ping to.
true if the server at the given address responded to the ping successfully.
NullPointerExceptionIf the address is null.
protected void serverError(Socket socket, Throwable e)
Called in case an exception is encountered during the operation of the RMIServer.

The argument exception may be cause by IO errors, SSL exceptions, or by other reasons. Implementations can deal with the exception in any way fit.

If an exception is thrown from this method, its stacktrace will be printed to the standard error.

The default implementation prints the exception to the standard error.

socketThe socket to which the exception relates. May be null if the exception occurs when accepting clients.
eThe exception.
saker.rmi 0.8.2
public final void setConnectionTimeout(int connectionTimeout)
Sets the connection timeout for the accepted sockets.

This is the timeout in milliseconds for read operations on the accepted sockets. Negative value means that an implementation dependent default value is used.

Zero means infinite timeout, and also means that the RMIServer code won't call Socket.setSoTimeout(int) during initialization. In this case subclasses can set the timeout dynamically in validateSocket(Socket).

connectionTimeoutThe connection read timeout in milliseconds.
saker.rmi 0.8.2
protected void setupConnection(Socket acceptedsocket, RMIConnection connection) throws IOException, RuntimeException
Sets up the accepted connection.

This method is called by the server when an accepted connection has been established, but before any streams are added to it.

If any exception is thrown by this method, the connection setup will be aborted, and it will be refused.

If implementations used an SSLSocketFactory or similar during instantiation of this server, they can use the argument socket to validate the identity of the client.

Implementations can use the RMIConnection.putContextVariable(String, Object) function of the connection, but should not start any RMI requests on it.

Implementations should not use the input and output streams of the accepted socket.

If this method returns successfully, the connections is deemed to be established.

acceptedsocketThe accepted socket.
connectionThe accepted connection.
IOExceptionIn case of I/O error.
RuntimeExceptionIf the validation of the socket failed.
public static void shutdownServer(SocketAddress address) throws IOException, NullPointerException
Sends a shutdown request to the RMI server running at the given address if any.

Works the same way a shutdownServer(SocketFactory, SocketAddress) with null socket factory.

addressThe address to shutdown the server at.
IOExceptionIn case of I/O error.
NullPointerExceptionIf the address is null.
Sends a shutdown request to the RMI server running at the given address if any.

A connection will be established to the given address, and the RMIServer running on that endpoint will be asked to shut down. (I.e. close itself)

The server will call its implementation validateShutdownRequest(Socket) method and will decide if it wants to satisfy the request. If the remote server is shutting down, this method will complete successfully.

If the connection failed to establish, an IOException will be thrown.

If the shutdown request is denied, an RMIShutdownRequestDeniedException will be thrown.

addressThe address to shutdown the server at.
socketconfigThe socket configuration to use.
IOExceptionIn case of I/O error.
RMIShutdownRequestDeniedExceptionIf the shutdown request was denied by the remote endpoint.
NullPointerExceptionIf any of the arguments are null.
saker.rmi 0.8.2
Sends a shutdown request to the RMI server running at the given address if any.

Works the same way as shutdownServer(SocketAddress, RMISocketConfiguration) with the given socket factory and defaults.

socketfactoryThe socket factory to use for connection, or null to use none.
addressThe address to shutdown the server at.
IOExceptionIn case of I/O error.
RMIShutdownRequestDeniedExceptionIf the shutdown request was denied by the remote endpoint.
NullPointerExceptionIf the address is null.
public final void start() throws IllegalStateException
Starts the accepting of connections on a separate thread.

This method is the same as calling start(ThreadGroup) with null thread group.

IllegalStateExceptionIf the RMI server was already started previously.
public final void start(ThreadGroup threadpoolthreadgroup) throws IllegalStateException
Starts the accepting of connections on a separate thread.

This method will create a thread pool and start listening for connections in one of the threads. The thread pool will be used to handle the accepted connections. The threads in the thread pool are daemon threads (including the one listening for connections), however users should not rely on this behaviour.

The argument thread group will be used as a parent thread group for the started threads in the thread pool.

threadpoolthreadgroupThe thread group for the thread pool or null to use the current one.
IllegalStateExceptionIf the RMI server was already started previously.
public final void start(Executor executor) throws NullPointerException, IllegalStateException
Starts the accepting of connections on a given executor.

This method will start listening for connections using the argument executor. The handling of new connections will also use the given executor.

executorThe executor to accepts connections and handle new connections on.
NullPointerExceptionIf the executor is null.
IllegalStateExceptionIf the RMI server was already started previously.
saker.rmi 0.8.3
protected boolean validateConnectionStream(Socket acceptedsocket, RMIConnection connection) throws IOException
Checks if the newly accepted socket can be used to add a new stream to the argument RMI connection.

This method is called by the server when a new stream is being added to a connection. This is after a socket connections is accepted, and before a new stream for it is constructed.

Implementations are presented an opportunity to disallow the use of the accepted socket for the specified connection. They should return false if the socket can't be used.

The default implementation returns true.

acceptedsocketThe accepted socket.
connectionThe connection to which the new stream is being added to.
true if the socket can be used to access the specified connection.
IOExceptionIn case of I/O error.
protected boolean validatePingRequest(Socket requestsocket)
Checks if this server should respond to a ping request from the given socket successfully.

This method is called when a socket connection is accepted from a client and a ping request is being served.

It is recommended that this method does any validation in regards if the socket would be able to successfully initiate a connection to this server.

The default implementation returns true.

This method should not throw any exceptions, but validation failures should be represented by returning false.

requestsocketThe socket which initiated the ping request.
true if the pining is successful.
protected boolean validateShutdownRequest(Socket requestsocket)
Checks if the RMI server can be shut down externally from the specified socket.

This method is called when a server accepts a socket connection that requests this RMI server to be shut down.

Implementations are presented an opportunity to disallow the shutdown request. They should return false if the RMI server should not be shut down.

This method should not throw any exceptions, but validation failures should be represented by returning false.

requestsocketThe socket which requests the shutdown.
true if this RMI server should be shut down.
protected void validateSocket(Socket accepted) throws IOException, RuntimeException
Called right after a client connection has been accepted.

Implementations can use this method to validate or log information related to the accepted socket. In case of SSL connections, subclasses may perform validations.

Implementations should not use the input and output streams of the accepted socket.

If an exception is thrown from this method, the socket will be closed.

The default implementation does nothing.

acceptedThe accepted connection.
IOExceptionIn case of errors.
RuntimeExceptionIn case of errors.
saker.rmi 0.8.2