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 can 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 abstract 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:
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 simple peer-to-peer remote
object that is not implemented by extending the 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 in which an "unexported" remote object is passed as an argument
or return value.
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.
The exportObject
method returns a RemoteStub
which is the stub object for
the remote object, obj, that is passed in place of the remote object in an RMI
call.
UnicastRemoteObject
is passed as
a parameter or return value in an RMI call, the object is replaced by the remote
object's stub. A remote object implementation remains in the virtual machine
in which it was created and does not move (even by value) from that virtual
machine. In other words, a remote object is passed by reference in an RMI call;
remote objects cannot be passsed by value.
UnicastRemoteObject
is transient and is not saved
if an object of that type is written to a user-defined ObjectOutputStream
(for
example, if the object is written to a file using serialization). An object that is
an instance of a user-defined subclass of UnicastRemoteObject
, however,
may have non-transient data that can be saved when the object is serialized.
When a UnicastRemoteObject
is read from an ObjectInputStream
, it is
automatically exported to the RMI runtime so that it may receive RMI calls. If
exporting the object fails for some reason, deserializing the object will
terminate with an exception.
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 clients holding remote references to it. The
distributed garbage collection mechanism maintains for each remote object, the
set of client virtual machines that hold references that remote object. As long as
some client holds a remote reference to the remote object, the RMI runtime
keeps a local reference to the remote object. When the "reference" set becomes
empty, the Unreferenced.unreferenced
method is invoked (if the server
implements the Unreferenced
interface). A remote object is not required to
support the Unreferenced
interface.
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 the reference set becomes
empty, Unreferenced
will be invoked. As such, the Unreferenced
method
can 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(); // Returns implementation specific security context public Object getSecurityContext(); // Disallow creating classloaders 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; // 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 stubs from using IP multicast. public void checkMulticast(InetAddress maddr) throws RMISecurityException; // Disallow stubs from using IP multicast public void checkMulticast(InetAddress maddr, byte ttl) throws RMISecurityException; // Downloaded classes (including stubs) can make connections if // called through the RMI transport. public synchronized void checkConnect(String host, int port) throws RMISecurityException; // Downloaded classes (including stubs) can make connections if // called through the RMI transport. public void checkConnect(String host, int port, Object context) 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; // Disallow stubs from accessing system clipboard. public void checkSystemClipboardAccess() throws RMISecurityException; // Disallow stubs from accessing AWT event queue. public void checkAwtEventQueueAccess() 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; // Stubs cannot perform security provider operations. public void checkSecurityAccess(String provider) 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. A downloaded class is allowed to make a connection
if the connection was initiated via the RMI transport.
If no security manager has been set, stub loading is disabled. This ensures that
some security manager is responsible for the actions of loaded stubs and
classes as part of any remote method invocation. A security manager is set
using System.setSecurityManager
.
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; public static Object getSecurityContext(ClassLoader loader); }
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.
The getSecurityContext
method returns the security context of the given
class loader, loader. The security context is obtained by querying the
LoaderHandler
's getSecurityContext
method.
The RMI runtime uses its own class loader to load stubs, skeletons, and
other classes needed by the stubs and skeletons. These classes, and the way
they are used, support the safety properties of the Java RMI runtime. This class
loader always loads locally-available classes first. Only if a security manager is
in force will stubs be loaded from either the local machine or from a network
source.
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,
such as http and ftp.
package java.rmi.server; public interface LoaderHandler { Class loadClass(String name) throws MalformedURLException, ClassNotFoundException; Class loadClass(URL codebase,String name) throws MalformedURLException, ClassNotFoundException; Object getSecurityContext(ClassLoader loader); }
LoaderHandler
interface must be implemented by a class named
LoaderHandler
. The LoaderHandler
class must be defined in the package
specified by the property java.rmi.loader.packagePrefix
. The methods
of LoaderHandler
are used by the java.rmi.server.RMIClassLoader
class to carry out its operations.
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 obtains 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. Note that the
RMISocketFactory may only be set if the current security manager allows
setting a socket factory; if setting the socket factory is disallowed, a
SecurityException
will be thrown.
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. 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. 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 java.io.PrintStream { public static LogStream log(String name); 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 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 representation.
The 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.
javac
.
javac
command line arguments are applicable and can be used
with rmic
.