Topics:
java.rmi.server.RemoteObject
class implements the java.lang.Object
behavior for remote objects. The hashCode
and equals
methods are implemented to allow remote object references to be stored in hashtables and compared. The equals
method returns true if two Remote
objects refer to the same remote object. It compares the remote object references of the remote objects.The
toString
method returns a string describing the remote object. The contents and syntax of this string is implementation specific and may vary.All of the other methods of
java.lang.Object
retain their original implementations.
package java.rmi.server; public abstract class RemoteObject implements java.rmi.Remote, java.io.Serializable { public int hashCode(); public boolean equals(Object obj); public String toString(); }
java.rmi.server.RemoteServer
class is the common superclass to all server implementations and provides the framework to support a wide range of remote reference semantics. At present the only subclass supported is UnicastRemoteObject
.
package java.rmi.server; public class RemoteServer extends RemoteObject { public static String getClientHost() throws ServerNotActiveException; public static void setLog(java.io.OutputStream out);
public static java.io.PrintStream getLog(); }
getClientHost
method allows an active method to determine the host that initiated the remote method active in the current thread. The ServerNotActiveException
is thrown if no remote method is active on the current thread. The setLog
method logs RMI calls to the specified output stream. If the output stream is null, call logging is turned off. The getLog
method returns the stream for the RMI call log so that application specific information can be written to the call log in a synchronized manner.
java.rmi.server.UnicastRemoteObject
class provides support for point-to-point active object references using TCP-based streams. The class implements a remote server object with the following characteristics:
package java.rmi.server; public class UnicastRemoteObject extends RemoteServer { protected UnicastRemoteObject() throws java.rmi.RemoteException; public Object clone() throws java.lang.CloneNotSupportedException; public static void exportObject(java.rmi.Remote obj) throws java.rmi.RemoteException; }
UnicastRemoteObject
, the constructor creates and exports a remote object. The constructor is invoked from the corresponding constructor of the remote object class. The default constructor creates a new unicast remote object using an anonymous port.The clone method is used to create a unicast remote object with initially the same contents, but is exported to accept remote calls and is distinct from the original object.
exportObject
method is used to export a unicast remote object that is not implemented by extending UnicastRemoteObject
class. The exportObject
method is called with the object to be exported on an anonymous port. The object must be exported prior to the first time it is passed in an RMI call as either a parameter or return value; otherwise a java.rmi.server.StubNotFoundException
is thrown when a remote call is attempted.Once exported, the object can be passed as an argument in an RMI call or returned as the result of an RMI call. When a remote object is passed, during marshaling a lookup is performed to find the matching remote stub for the remote object implementation and that stub is passed or returned instead.
package java.rmi.server; public interface Unreferenced { public void unreferenced(); }
java.rmi.server.Unreferenced
interface allows a server object to receive notification that there are no remote references to it. The distributed garbage collection mechanism maintains a set of remote references to each remote object. As long as some client holds a remote reference the RMI runtime keeps a local reference to the remote object. When the set becomes empty the Unreferenced.unreferenced
method is invoked. No action is required by the implementation and it is not required to support Unreferenced
.As long as some local reference to the remote object exists it may be passed in remote calls or returned to clients. The process that receives the reference is added to the reference set for the reference. When those new references no longer exist
Unreferenced
will be invoked. As such, the Unreferenced
method may be called more than once, each time the set is newly emptied. Remote objects are only collected when no more references, either local references or those held by clients, still exist.
package java.rmi; public class RMISecurityManager extends java.lang.SecurityManager { // Constructor public RMISecurityManager(); // The host stub came from determines what stub can do public Object getSecurityContext(); //Disallow creating class loaders or execute ClassLoader methods public synchronized void checkCreateClassLoader() throws RMISecurityException; // Disallow thread manipulation public synchronized void checkAccess(Thread t) throws RMISecurityException; // Disallow thread group manipulation. public synchronized void checkAccess(ThreadGroup g) throws RMISecurityException; // Disallow exiting the VM public synchronized void checkExit(int status) throws RMISecurityException; // Disallow forking of processes public synchronized void checkExec(String cmd) throws RMISecurityException; // Disallow linking dynamic libraries public synchronized void checkLink(String lib) throws RMISecurityException; // Disallow accessing of all properties except those labeled OK public synchronized void checkPropertiesAccess() throws RMISecurityException;
// Access system property key only if key.stub is set to true public synchronized void checkPropertyAccess(String key) throws RMISecurityException; // Check if a stub can read a particular file. public synchronized void checkRead(String file) throws RMISecurityException; // Check if a stub can read a particular file. public synchronized void checkRead(String file, URL base) throws RMISecurityException; // No file reads are valid from a stub public void checkRead(String file, Object context) throws RMISecurityException; // Check if a Stub can write a particular file. public synchronized void checkWrite(String file) throws RMISecurityException; // Check if the specified system dependent file can be deleted. public void checkDelete(String file) throws RMISecurityException; // Disllow opening file descriptor for reading unless via socket public synchronized void checkRead(FileDescriptor fd) throws RMISecurityException; // Disallow opening file descriptor for writing unless via socket public synchronized void checkWrite(FileDescriptor fd) throws RMISecurityException; // Disallow listening on any port. public synchronized void checkListen(int port) throws RMISecurityException; // Disallow accepting connections on any port. public synchronized void checkAccept(String host, int port) throws RMISecurityException; // Disallow making connections on any port. public synchronized void checkConnect(String host, int port) throws RMISecurityException; // Disallow making connections on any port. public void checkConnect(String host, int port, Object context) throws RMISecurityException; // Disallow making connections on any port. public synchronized void checkConnect(String fromHost, String toHost) throws RMISecurityException; // Allow caller to create top-level windows. // Allow stubs to create windows with warnings. public synchronized boolean checkTopLevelWindow(Object window) throws RMISecurityException; // Check if a stub can access a package. public synchronized void checkPackageAccess(String pkg) throws RMISecurityException; // Check if a stub can define classes in a package. public synchronized void checkPackageDefinition(String pkg) throws RMISecurityException; // Check if a stub can set a networking-related object factory. public synchronized void checkSetFactory() throws RMISecurityException; // Disallow printing from stubs. public void checkPrintJobAccess() throws RMISecurityException; // Checks to see if client code can access class members. // Allow access to all public information. Allow non-stubs to // access default, package, and private declarations and data). public void checkMemberAccess(Class clazz, int which) throws RMISecurityException; }
RMISecurityManager
can be used when the application does not require specialized security functions but does need the protection it provides. This simple security manger disables all functions except class definition and access so that other classes for remote objects, their arguments and returns can be loaded as needed.If no security manager has been set, stub loading is disabled. This insures that some security manager must be responsible for the actions of loaded stubs and classes as part of any remote method invocation. A security manager is set using
System.setSecurityManager
.
The class loader keeps a cache of loaders for individual Uniform Resource Locators (URLs) and the classes that have been loaded from them. When a stub or skeleton has been loaded, any class references that occur as parameters or returns will be loaded (from their originating codebase host) and are subject to the same security restrictions.
Server processes must declare to the RMI runtime the location of the classes (stubs and parameters/returns) that will be available to its clients. The
java.rmi.server.codebase
property should be a URL from which stub classes and classes used by stubs will be loaded, using the normal protocols, for example http, ftp, etc...The
java.rmi.server.RMIClassLoader
is a utility class that can be used by applications to load classes via a URL.
package java.rmi.server; public class RMIClassLoader { public static Class loadClass(String name) throws MalformedURLException, ClassNotFoundException public static synchronized Class loadClass(URL codebase, String name) throws MalformedURLException, ClassNotFoundException }
loadClass
method loads the specified class name via the URL defined by the java.rmi.server.codebase
property. The class is loaded, defined, and returned.The second form of the loadClass method loads the specified class name via the URL parameter codebase.
java.rmi.server.RMISocketFactory
abstract class provides an interface for specifying how the transport should obtain sockets.
package java.rmi.server; public abstract class RMISocketFactory { public abstract java.net.Socket createSocket(String h,int p) throws IOException; public abstract java.net.ServerSocket createServerSocket(int p) throws IOException; public static void setSocketFactory(RMISocketFactory fac) throws IOException; public static RMISocketFactory getSocketFactory(); public static void setFailureHandler(RMIFailureHandler fh); public static RMIFailureHandler getFailureHandler(); }
setSocketFactory
is used to set the socket factory from which RMI gets sockets. The application may invoke this method with its own RMISocketFactory
instance only once. An application-defined implementation of RMISocketFactory
could, for example, do preliminary filtering on the requested connection and throw exceptions, or return its own extension of the java.net.Socket
or java.net.ServerSocket
classes, such as ones that provide a secure communication channel.The static method
getSocketFactory
returns the socket factory used by RMI. The method returns null if the socket factory is not set.The transport layer invokes the
createSocket
and createServerSocket
methods on the RMISocketFactory
returned by the getSocketFactory
method when the transport needs to create sockets, for example:
RMISocketFactory.getSocketFactory().createSocket(myhost, myport)
createSocket
should create a client socket connected to the specified host and port. The method createServerSocket
should create a server socket on the specified port. The default transport's implementation of RMISocketFactory
provides for transparent RMI through firewalls using HTTP as follows:
createSocket
, the factory automatically attempts HTTP connections to hosts that cannot be contacted with a direct socket
createServerSocket
, the factory returns a server socket that automatically detects if a newly accepted connection is an HTTP POST request, and if so, it returns a socket that will transparently expose only the body of the request to the transport and format its output as an HTTP response.
setFailureHandler
sets the failure handler to be called by the RMI runtime if the creation of a server socket fails. The failure handler returns a boolean to indicate if retry should occur, and the default failure handler returns false, meaning that by default recreation of sockets is not attempted by the runtime.The method
getFailureHandler
returns the current handler for socket creation failure, or null if the failure handler is not set.
java.rmi.server.RMIFailureHandler
interface provides a method for specifying how the RMI runtime should respond when server socket creation fails.
package java.rmi.server;
public interface RMIFailureHandler { public boolean failure(Exception ex); }
failure
method is invoked with the exception that prevented the RMI runtime from creating a java.net.Socket
or java.net.ServerSocket
. The method returns true if the runtime should attempt to retry and false otherwise.Before this method can be invoked, a failure handler needs to be registered via the
RMISocketFactory.setFailureHandler
call. If the failure handler is not set, creation is not attempted.
LogStream
presents a mechanism for logging errors that are of possible interest to those monitoring the system. This class is used internally for server call logging.
package java.rmi.server; public class LogStream extends PrintStream { public static LogStream log(String name); public static void showThreadName(boolean doIt); public static synchronized PrintStream getDefaultStream(); public static synchronized void setDefaultStream(
PrintStream newDefault); public synchronized OutputStream getOutputStream(); public synchronized void setOutputStream(OutputStream out); public void write(int b); public void write(byte b[], int off, int len); public String toString(); public static int parseLevel(String s); // constants for logging levels public static final int SILENT = 0; public static final int BRIEF = 10; public static final int VERBOSE = 20; }
log
returns the LogStream identified by the given name. If a log corresponding to name does not exist, a log using the default stream is created.The method
showThreadName
sets whether thread names are part of the message label.The method
getDefaultStream
returns the current default stream for new logs.The method
setDefaultStream
sets the default stream for new logs.The method
getOutputStream
returns current stream to which output from this log is sent.The method
setOutputStream
sets the stream to which output from this log is sent.The first form of the method
write
writes a byte of data to the stream. If it is not a new line, then the byte is appended to the internal buffer. If it is a new line, then the currently buffered line is sent to the log's output stream with the appropriate logging prefix. The second form of the method write
writes a subarray of bytes.The method
toString
returns log name as string representationThe method
parseLevel
converts a string name of a logging level to its internal integer representation.
rmic
stub and skeleton compiler is used to compile the appropriate stubs and skeletons for a specific remote object implementation. The compiler is invoked with the package qualified class name of the remote object class. The class must previously have been compiled successfully.