In previous releases, after a remote object had been exported on
an explicit (non-anonymous) TCP port, the RMI implementation would
keep a server socket bound to that port open for the lifetime of the
virtual machine, regardless of the life cycle of remote objects
exported on that port. This bug has been fixed so that after all
remote objects that had been exported on a given non-anonymous port
have become unexported (either explicitly or through distributed
garbage collection) then the associated server socket will be closed.
(There is an equivalent bug for anonymous TCP ports: 6279965.)
Bug fix: Garbage collection of client socket factories (4486732)
In previous releases, after a remote invocation was made on a
remote stub containing a non-nullRMIClientSocketFactory
in a given virtual machine, then either that factory object or an
equivalent factory object would remain forever reachable in the
virtual machine, preventing it (and its defining class loader) from
ever being garbage collected; this bug has been fixed. (There is an
equivalent bug for socket factories used to export a remote object: 6332603.)
Default GC interval lengthed to one hour (6200091)
In previous releases, the maximum interval between garbage
collections of the local heap enforced by the RMI implementation
(while there are live remote references or exported remote objects),
which is controlled by the system properties
sun.rmi.dgc.client.gcInterval and
sun.rmi.dgc.server.gcInterval, was one minute by default.
The default interval is now one hour, to better accommodate
applications with large heap sizes without special configuration.
Enhancements and Changes in Previous Releases
Dynamic Generation of Stub Classes (since 5.0)
This release adds support for the dynamic generation of
stub classes at runtime, obviating the need to use the Java
Remote Method Invocation (Java RMI) stub
compiler, rmic, to pregenerate stub classes for remote
objects. Note that rmic must still be used to
pregenerate stub classes for remote objects that need to support
clients running on earlier versions.
When an application exports a remote object (using the
constructors or static exportObject methods1 of the
classes java.rmi.server.UnicastRemoteObject or
java.rmi.activation.Activatable) and a pregenerated
stub class for the remote object's class cannot be loaded, the
remote object's stub will be a
java.lang.reflect.Proxy instance (whose class is
dynamically generated) with a
java.rmi.server.RemoteObjectInvocationHandler as its
invocation handler.
An existing application can be deployed to use dynamically
generated stub classes unconditionally (that is, whether or not
pregenerated stub classes exist) by setting the system property
java.rmi.server.ignoreStubClasses to
"true". If this property is set to
"true", pregenerated stub classes are never used.
Notes:
If a remote object has pre-5.0 clients, that remote object
should use a stub class pregenerated with rmic or
the client will get an ClassNotFoundException
deserializing the remote object's stub.
Pre-5.0 clients will not be able to load an instance of a
dynamically generated stub class, because such a class contains
an instance of RemoteObjectInvocationHandler, which
was not available prior to this release.
Prior to the J2SE 5.0 release, exporting a remote object would
throw a java.rmi.StubNotFoundException if the
pregenerated stub class for the remote object's class could not
be loaded. With the added support for dynamically generated stub
classes, exporting a remote object that has no pregenerated stub
class will silently succeed instead. A user deploying a server
application to support pre-5.0 clients must still make sure to
pregenerate stub classes for the server's remote object classes,
even though missing stub classes are no longer reported at
export time. Such errors will instead be reported to a pre-5.0 client
when it deserializes a dynamically generated stub class.
1 The static method
UnicastRemoteObject.exportObject(Remote) is declared to
return java.rmi.server.RemoteStub and therefore
cannot be used to export a remote object to use a dynamically
generated stub class for its stub. An instance of a dynamically
generated stub class is a java.lang.reflect.Proxy
instance which is not assignable to RemoteStub.
Standard SSL/TLS Socket Factory Classes (since 5.0)
This release adds standard Java RMI socket factory classes, javax.rmi.ssl.SslRMIClientSocketFactory
and javax.rmi.ssl.SslRMIServerSocketFactory,
which communicate over the Secure Sockets Layer (SSL) or Transport
Layer Security (TLS) protocols using the Java Secure Socket Extension
(JSSE). These socket factory classes provide a simple way to use JSSE
with Java RMI, enabling enforcement of integrity, confidentiality
(through encryption), server authentication, and (optionally) client
authentication for remote method invocations. For more information on
how to use custom socket factories with Java RMI, see the tutorial "Using Custom Socket Factories with Java
RMI". For more information on JSSE (including how to configure
it), see the JSSE
Reference Guide.
Launching rmid or a Java RMI Server from
inetd/xinetd (since 5.0)
A new feature, provided by the
System.inheritedChannel method, allows an
application to obtain a channel
(java.nio.channels.SocketChannel or
java.nio.channels.ServerSocketChannel, for example)
inherited from a process that launched the virtual machine (VM).
Such an inherited channel can be used to either service a single
incoming connection (in the case of a
SocketChannel) or accept multiple incoming
connections (in the case of ServerSocketChannel).
Therefore, Java networking applications launched by
inetd (Solaris(tm) Operating System) or
xinetd (Linux) can now obtain the
SocketChannel or ServerSocketChannel
inherited from inetd/xinetd.
With the addition of this feature, the Java RMI activation
daemon rmid has been enhanced to support being
launched from inetd/xinetd so that rmid
can be started up only when it receives an incoming connection.
For details on the enhancements to rmid to support
this feature, see the tools page for rmid (for
the Solaris Operating System). For details on how to
configure inetd to launch rmid, see the
tutorial "Configuring
inetd to Launch rmid".
An application using Java RMI can also be designed to be launched
from inetd or xinetd. For an example
on how to implement this technique, see the tutorial "Designing Services to be Launched from
inetd."
rmic default stub protocol version option now -v1.2
(since 5.0)
When rmic is run without an option to specify the JRMP
stub protocol version to be used by the generated classes, it now
behaves as if the -v1.2 option were specified, instead of
the -vcompat option as in previous releases.
This change means that by default, rmic does not
generate any skeleton classes and generates stub classes that only
implement the 1.2 stub protocol version. If a remote implementation
class needs to be built to support clients running on JDK 1.1, then
the -vcompat option must now be specified explicitly.
(Also, note that as described above, if a remote implementation class
does not need to support clients running on any release prior to 5.0,
then rmic does not need to be run at all for that class.)
See the tools documentation for rmic [Solaris and Linux] [Windows] for more
information about these command line options.
rmic no longer compiles arbitrary source files in the
class path (since 5.0)
In previous releases, rmic would sometimes, while
processing its input class files, attempt to compile arbitrary
.java source files that it encountered in the class path.
In 5.0, rmic does not attempt to compile any source files
other than those for the stub, skeleton, or tie classes that it
generates.
The expectation is that the remote implementation classes passed to
rmic, as well as all classes and interfaces that they
depend on, have already been successfully compiled with
javac before rmic is run. If an existing
build procedure depends on the previous behavior of rmic
for compiling some of its application source files, then that build
procedure will need to be modified to ensure that all necessary
classes are correctly compiled with javac before running
rmic.
Server-side Stack Traces Now Retained in Remote Exceptions (since 1.4)
The Java RMI runtime implementation will now preserve the
server-side stack trace information of an exception that is thrown from
a remote call, in addition to filling in the client-side stack trace as
it did in previous releases. Therefore, when such an exception becomes
accessible to client code, its stack trace will now contain all of its
original server-side trace data followed by the client-side trace.
This feature is made possible by the new "programmatic access to stack
trace information" feature of java.lang.Throwable in J2SE 1.4, which
included making a Throwable's stack trace data part of its
default serialized form. What the client-side Java RMI runtime implementation now
does to cooperate with this feature is to append the client-side trace
to the unmarshalled server-side trace, rather than simply overwriting
with the client-side trace as it did in previous releases.
Certain server applications may wish to prevent any server-side
stack trace data from accompanying an exception to be marshalled as the
result of a remote call (as part of the exception's default serialized
form in J2SE 1.4), perhaps for reasons of performance or
confidentiality. In such cases, the implementation-specific system
property
can be set to "true" to cause the server-side Java RMI runtime
implementation to clear the stack traces of all exceptions thrown from
the current virtual machine as the result of remote method invocations.
Service Provider Interface for RMIClassLoader (since 1.4)
Certain static methods of java.rmi.server.RMIClassLoader
now delegate their behavior to an instance of a new service provider
interface, java.rmi.server.RMIClassLoaderSpi. The service
provider can be configured to augment the Java RMI dynamic class loading
behavior for a given application. By default, the service provider
implements the standard behavior of all of the static methods in
RMIClassLoader. See the class documentation of
RMIClassLoader and
RMIClassLoaderSpi for more details.
Dynamic Server Host Name (since 1.4)
The java.rmi.server.hostname property can now be
dynamically updated to indicate that future exports should use a new
host name. Therefore, the new host name value will be contained in the stub
for an object that is exported after the property is updated.
HTTP Fallback Is More Configurable (since 1.4.1)
The implementation-specific system property
sun.rmi.transport.proxy.eagerHttpFallback
has been added to allow additional control over when the Java RMI default socket
factory will fall back to HTTP tunneling. This property configures the
default socket factory so that any SocketException thrown by an initial
(direct) connection attempt will trigger HTTP tunneling; this more "eager"
fallback strategy can be useful when dealing with firewalls which deny
instead of ignore connection attempts to unauthorized ports.
java.rmi.Naming.list Method No Longer Prepends a Scheme to Names Returned (since 1.4.1)
In previous releases, the Naming.list method prepended
the scheme rmi: to each name contained in the returned
array of strings. The Naming.list implementation now
matches the specification, returning an array of names that are
URL-formatted, but without the scheme component.
The getClassName method, which returns the group's class
name, can now return null, indicating the system's default group
implementation. Previously, the getClassName method would
return the name of the internal implementation class if the default
group implementation was chosen when the descriptor was constructed.
Due to this change, if an application running in a 1.3 virtual machine registers an
new activatable object with the ActivationSystem,
rmid must also be upgraded to run 1.3, since a pre-1.3
rmid will not be able to activate the newly registered
activatable object.
The Java RMI Stub Compiler, rmic (since 1.3)
By default, rmic [Solaris and Linux] [Windows] now assumes that the destination
directory for generated stubs is the package-named subdirectory of the
current working directory. If the "-d" option is not
specified, the result is the same as though it were specified with the
current working directory "." as an argument. The "-d"
may still be used to override the default destination directory.
Two new options, "-idl" and "-iiop" have been added to
generate IDL and stubs for IIOP, respectively.
Prior to 1.2.2, an attempt to pass an unexported remote object in a RMI
call would result in a java.rmi.StubNotFoundException.
This exception was a result of the RMI runtime's failure to locate a
stub object during an attempt to replace a remote object implementation
with its corresponding stub. In 1.2.2 and later releases, an unexported
remote object passed in an RMI call will no longer result in an
exception, but rather the remote object will be serialized instead of
its stub. If the remote object implementation is not serializable, an
attempt to pass an unexported object in an RMI call will result in a
java.rmi.RemoteException with the nested exception
java.io.NotSerializableException.