Support Readiness Document Java 2 Standard Edition 1.3 Remote

Support Readiness Document
Java 2 Standard Edition 1.3
Remote Method Invocation
Sun Microsystems, Inc.
Market Development & Developer Relations
Support Readiness Education
Support Readiness Document
Java 2 Standard Edition 1.3
Remote Method Invocation
Sun Microsystems, Inc.
Market Development & Developer Relations
901 San Antonio Road
Palo Alto, CA 94303
Version: 1.3
Release Date: March 30, 2000
 2000 by Sun Microsystems, Inc.—Printed in USA.
901 San Antonio Road, Palo Alto, CA 94303-4900
All rights reserved. No part of this work covered by copyright may be duplicated by any
means—graphic, electronic or mechanical, including photocopying, or storage in an information
retrieval system—without prior written permission of the copyright owner.
RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the government is subject to
restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer
Software clause at DFARS 252.227-7013 (October 1988) and FAR 52.227-19 (June 1987). The
product described in this manual may be protected by one or more U.S. patents, foreign patents,
and/or pending applications.
TRADEMARKS: Java, JVM, Solaris, Solstice, NFS, are trademarks of Sun Microsystems, Inc.
Solaris SPARC (Platform Edition) is a trademark of Sun Microsystems, Inc. All SPARC
trademarks are used under license and are trademarks or registered trademarks of SPARC
International, Inc. in the United States and other countries. Products bearing SPARC trademarks
are based upon an architecture developed by Sun Microsystems, Inc. UNIX is a registered
trademark in the United States and other countries, exclusively licensed through X/Open
Company, Ltd.
Sun Microsystems, Inc.
Market Development & Developer Relations
901 San Antonio Road
Palo Alto, CA 94303
Table of Contents
Table of Contents
Preface iv
1.0 Remote Method Invocation Overview
1.1 Features, Advantages, and Benefits 1
1.1.1 Command Tools 2
1.1.2 Packages 2
1.1.3 Classes and Interfaces 2
1.2 New in the Java 2 Platform, Version 1.3
1.2.1 Serialization Enhancements (Notably for RMI)
1.2.2 RMI Enhancements 3
1.2.3 Changes to the rmic command 4
1.3 New in the Java Development Kit, Version 1.2
Changes to the RMI Socket Factories 4
New Features Supporting Remote Object Activation 5
New Options to the rmic Command 5
Changes Since JDK 1.1.x 5
Changes to Remote Interface Definition 5 Remote Interfaces 5 Remote Exceptions 5
1.3.6 API Changes 6 java.rmi.RMISecurityManager 6 java.rmi.registry.LocateRegistry 6 java.rmi.server.ObjID 6 java.rmi.server.RMIClassLoader 6 java.rmi.server.RMISocketFactory 6 java.rmi.server.UnicastRemoteObject 7 java.rmi.server.useLocalHostname Property
1.3.7 Change to the URL Codebase 7
1.3.8 New Stubs and No Skeletons 7
1.4 Localization and Internationalization 7
2.0 Product Distribution
3.0 Requirements and Dependencies
3.1 System Requirements and Dependencies 8
3.2 Software Requirements and Dependencies 8
3.2.1 Product Dependencies 8
3.2.2 Other Software Requirements 9
3.2.3 Default Permanent IP Address 9
3.3 Product Limitations 9
3.4 Product Compatibility 10
3.4.1 Interoperability With Existing Sun and Third-Party Software Internet Inter-Orb Protocol 10 Hypertext Transfer Protocol 10
3.4.2 Versions 10
Table of Contents Previous Versions 10 Java 2 Platform 10
3.4.3 Backward/Forward Compatibility With Other Versions Version 1.0.2 10 Version 1.1 11 Version 1.2 11 Version 1.3 11
4.0 Configuration
General Configuration 11
Configuration for Use With a Firewall 12
Configuration for Use With Signed Jar Files
RMI Properties 12
4.4.1 java.rmi Properties 13
4.4.2 sun.rmi Properties 13
5.0 Changes to the Command Tools
5.1 The RMI Compiler - rmic 15
5.1.1 New Options to rmic (Since Java 2 Version 1.3) 15
5.1.2 New Options to rmic (Since Java 2 Version 1.2) 15
5.1.3 Reduced Constraints on the Remote Interfaces Handled by rmic 16
5.2 The RMI Activation Daemon - rmid 16
5.2.1 Logging 16
5.2.2 Options 16
6.0 Administering RMI
7.0 Bug Fixes
RMI Bugs Fixed in Java 2 Version 1.3 17
RMI Bugs Fixed in Java 2 Version 1.2.2 21
RMI Bugs Fixed in Java 2 Version 1.2.1 24
RMI Bugs Fixed in Java 2 Version 1.2.0 24
8.0 Using RMI
8.1 Downloadable Client Socket Factories
8.2 Activatable Objects 26
9.0 Tuning and Troubleshooting
9.1 Installation and Configuration Caveats
rmiregistry: CLASSPATH Without the Application’s Classes 27
File Descriptor Limit 27
Server IP Address 27
Security Policy Files 27
Specifying Codebase 28
ClassNotFoundException If Loading Classes From a Web Server
9.2 Common User or System Administrator Errors 28
9.3 Common User Questions 28
9.4 Error Message Guide 29
Table of Contents
9.5 Known Bugs and Their Workarounds
9.6 Troubleshooting Utilities 30
Relating RMI References to Host Names and Port Numbers
Codebase Debugging 30
Strategic Printing of Program State 30
Running a Backtrace 31
System Properties 31
9.7 Performance and Tuning Recommendations 31
10.0 Reference Information
10.1 Technical Documentation
Java Remote Method Invocation Specification 32
Starting Point for RMI Documentation 32
Additional Online Documentation 32
API Documentation 32
RMI Tutorials 32
10.2 Additional References 32
This document provides Support Readiness information for Java 2 Standard Edition 1.3
Remote Method Invocation. The goal of Support Readiness Documents (SRDs) is to
help support engineers prepare to support Software Products and Platforms Division
products. SRDs are not designed to provide comprehensive product training (see the
product documentation or Sun Education for this). Instead, they focus on issues immediately relevant to support, such as installation, configuration, and common user problems.
Document Format Options: PDF and PostScript
The “Java 2 Standard Edition 1.3 Remote Method Invocation SRD” can be viewed in
PostScript or PDF format. The PDF version of the document allows navigation via a
table of contents frame, and the benefit of live cross references and web links. Text that
is underlined and in blue, such as the URL in this paragraph, are clickable links in the
PDF version of the document. (Note: page numbers in the PDF document refer to
printed pages, and will not coincide with the page numbers in the PDF reader status
bar.) Although the blue color and underlining appear in the PostScript version, there are
no live links when viewing that version.
Typographic Conventions
This document uses the following type conventions:
• The names of commands, files, Java™ objects, Java classes, and directories are
shown in regular monospace font.
• Text that is a placeholder to be replaced with a real name or value appears in italic
type; for example: % unzip -d destination directory.
• Text that you type, when shown alongside computer output such as a command
prompt, is shown in bold monospace font. The marker "prompt>," in regular
monospace font, represents the actual command prompt you would see on your
screen, which may vary depending on your specific environment, shell, or platform.
For example: Solaris prompt> ls -l.
• The names of menu items, buttons, windows, and keyboard keys appear in regular
font with initial capitals, such as the Enter key.
• URLs that are clickable web links in the PDF version of the document are shown in
blue, underlined monospace font, as in Although the blue
color and underlining appears in the PostScript version, there are no live links when
viewing that version.
• URLs that are not clickable web links are shown in regular monospace font, such as
• Cross-references to other sections of the document are shown in regular font but are
blue and underlined, as in, See Section 1.0, “JSDT Overview.” In the PDF version of
the document, these are clickable links to the indicated section. Although the blue
color and underlining appears in the PostScript version, there are no live links when
viewing that version.
• New terms and book titles appear in italic type.
Java 2 Standard Edition 1.3
Remote Method Invocation
1.0 Remote Method Invocation Overview
The Java™ 2 Remote Method Invocation (RMI) application programming interface
(API) enables objects in one Java Virtual Machine (JVM™) to invoke methods on
objects in a different JVM. Because RMI is designed for communication between
JVMs, it allows objects to be passed as arguments or return values in a completely
object-oriented way. If an object’s class is unknown, the compiled Java code for its class
can be dynamically loaded by the recipient.
Note the following:
• A related extension now exists that allows RMI to operate over the Internet Inter-Orb
Protocol (IIOP) in addition to its native protocol. This extension is distinct from the
“core” RMI classes (java.rmi.*) discussed in this document, and is covered in a
separate document to be posted on by December, 2000.
• The Java 2 platform was previously known as the JDK™ 1.2.
1.1 Features, Advantages, and Benefits
RMI offers several features that make it attractive for use in programming distributed
applications because it:
• Presents a language-standard mechanism for invoking method calls between objects
that reside on different Java virtual machines.
• Eliminates the need to define custom wire protocols for networked applications,
since the RMI protocol is part of the core Software Development Kit (SDK).
• Offers a built-in mechanism for downloading new class definitions as needed from
URL-specified locations, allowing migration of both code and data over the network.
The command tools, packages, basic classes and interfaces that comprise RMI are enumerated in the following lists:
1 of 32
Remote Method Invocation Overview
Command Tools
• rmic – a development tool for generating stub/skeleton classes
• rmid – a runtime daemon which manages activatable objects
• rmiregistry – a daemon that provides an initial naming service
java.rmi – the principal classes needed by remote callers
java.rmi.activation – the additional classes needed by activatable objects
java.rmi.dgc – interfaces used for Distributed Garbage Collection (DGC)
java.rmi.registry – the classes used to interact with a Registry
java.rmi.server – the classes needed by exporters of remote objects
Classes and Interfaces
java.rmi.Remote – marker interface for stub-replaceable objects
java.rmi.RemoteException – common parent of RMI-related exceptions
java.rmi.RMISecurityManager – a security manager
java.rmi.Naming – convenience methods for locating and using Registries
java.rmi.server.UnicastRemoteObject – a convenient remote-object
• java.rmi.activation.Activatable – a convenient activatable-object
• java.rmi.activation.ActivationGroup – a grouping of activatable objects
in a JVM
• java.rmi.activation.ActivationDesc – metadata for an activatable object
• java.rmi.activation.ActivationGroupDesc – metadata for an activated
• java.rmi.server.RMIClassLoader – the classloader used by RMI
• java.rmi.server.RMIClientSocketFactory – for per-object invocation
• java.rmi.server.RMIServerSocketFactory – for per-object connection
• java.rmi.server.RMISocketFactory – for per-VM socket factories
1.2 New in the Java 2 Platform, Version 1.3
Serialization Enhancements (Notably for RMI)
Prior to 1.3, an attempt to serialize a string longer than 64K would result in a being thrown. In 1.3, the serialization protocol has been enhanced to allow strings longer than 64K to be serialized. RMI will also
allow these longer strings to be passed in RMI calls between 1.3-compatible Java virtual
machines (JVMs). Note that if a 1.2 (or earlier) JVM attempts to read a long string writ-
2 of 32
Remote Method Invocation Overview
ten from a 1.3-compatible JVM, the 1.2 (or earlier) JVM will receive a
UCS transformation format (UTF)1 read and write performance has improved significantly in 1.3. Additionally, writing the fields of an object during default serialization and
reading the fields of an object during default deserialization is up to 20% faster. Other
general implementation improvements have also increased performance up to an additional 20%. These serialization improvements have increased the overall performance of
RMI calls that pass objects as parameters or return values.
If a class cannot be found during the class resolution process of deserialization, the original java.lang.ClassNotFoundException is thrown instead of a generic one so
that more information about the failure is available. Another improvement to deserialization exception reporting is maintaining the name of the original class that could not
be found instead of reporting a higher-level class that was being deserialized. For example, if (in an RMI call) the stub class can be found but the remote interface class cannot,
the serialization mechanism will now report correctly that the interface class was the
class that could not be found instead of erroneously reporting that the stub class could
not be found.
RMI Enhancements
The java.rmi.activation.ActivationGroupDesc.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 JVM registers a 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.
An activatable object’s “activation” constructor, which takes an ActivationID and a
MarshalledObject as arguments and which is called by the
ActivationInstantiator each time the object is activated, can now be private or
protected. Previously, the implementation only allowed public activation constructors.
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
1. The acronym UTF stands for UCS Transformation Format. The term UCS is an acronym for Universal Character Set, which is also known as Universal Multiple-Octet Coded Character Set. Java uses a 16-bit character
length variant of the UCS sometimes referred to as UCS-2 or the Basic Multilingual Plane. See ISO/IEC Standard
10646-1:1993 at:
3 of 32
Remote Method Invocation Overview
java.rmi.server.RMIClassLoader has a new method, getClassLoader. This
method returns the class loader that RMI uses to load classes from a specified codebase
URL path. This API can be used in an implementation that requires complete RMI marshalling/unmarshalling behavior. For details, see the javadoc for
java.rmi.server.RMIClassLoader at:
Changes to the rmic command
By default, rmic 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 option may still be used to override the default
destination directory.
Two new options, -idl and -iiop, have been added to generate Interface Definition
Language (IDL) and stubs for IIOP respectively.
1.3 New in the Java Development Kit, Version 1.2
In JDK 1.2, RMI has several new enhancements.
Remote object activation introduces support for persistent references to remote objects
and automatic object activation by using these references.
Custom RMI client and server socket factories allow a remote object to specify the custom socket type that RMI will use for remote calls to that object. RMI over a secure
transport, such as the Secure Socket Layer (SSL), can be supported using custom socket
Minor API enhancements allow the following: unexporting a remote object, obtaining
the stub for an object implementation, and exporting an object on a specific port.
Changes to the RMI Socket Factories
In JDK 1.1, only the RMISocketFactory.setSocketFactory method was available to set a custom socket factory for RMI, and this method would globally set a socket
factory on a per-JVM basis; in the Java 2 platform, RMI socket factories can be assigned
on a per-object (remote object) basis.
In previous versions of RMI, a single socket factory that extended
java.rmi.server.RMISocketFactory was used for both the client and the server
applications. In the Java 2 platform, the socket factories used for client and server applications have been separated into two interfaces:
java.rmi.server.RMIClientSocketFactory and
In the JDK 1.2, RMI allows individual socket factories to be downloaded to clients,
whereas in JDK 1.1 the custom, global RMISocketFactory had to reside in the client’s local CLASSPATH.
4 of 32
Remote Method Invocation Overview
New Features Supporting Remote Object Activation
The package java.rmi.activation contains support classes and interfaces for
remote object activation. It also provides java.rmi.activation.Activatable,
an extendable (non-final) remote class similar in function to
A new daemon, rmid, has been added to facilitate object activation. The URLs to the
rmid manual pages are:
New Options to the rmic Command
Options beginning with -J are passed to the Java interpreter after
removing -J. This option is commonly used in conjunction with the -D
-vcompat (default) Creates stubs and skeletons compatible with both the JDK 1.1
and the Java 2 platform stub protocol versions.
Create stubs and skeletons for the JDK 1.1 stub protocol version.
Create stubs for the Java 2 platform stub protocol version only.
Has been removed from the manual page because it is no longer
recommended for use.
To view the rmic man pages, see:
Changes Since JDK 1.1.x
For information on additional changes, see
Changes to Remote Interface Definition
Remote Interfaces
A remote interface can now extend an interface that does not extend
java.rmi.Remote as long as all of the methods in the interface (if there are any)
throw a legal remote exception type. See Section, “Remote Exceptions.”
Remote Exceptions
A remote interface method can alternatively use any of the superclasses of
java.rmi.RemoteException, such as or
5 of 32
Remote Method Invocation Overview
java.lang.Exception, instead of RemoteException in the throws clause of the
API Changes java.rmi.RMISecurityManager
The RMISecurityManager has been updated to work with the new Java 2 platform
security model. Most of the RMISecurityManager methods are no longer overridden,
since the default behavior of the methods of java.lang.SecurityManager, which it
extends, is appropriate for the RMISecurityManager.
Note: If you do use the RMISecurityManager, you will need to use a policy file that
lists the permissions that are granted to code from various codebases. java.rmi.registry.LocateRegistry
Two new methods, createRegistry and getRegistry, have been added to the
LocateRegistry class.
The new createRegistry method takes a client socket factory and a server socket
factory as arguments. This method allows you to create a remote object registry that
uses custom client and server socket factories for communication with that registry.
The new getRegistry method takes a client socket factory as one of its arguments.
This method returns a locally created reference to a remote object registry that uses a
specified RMIClientSocketFactory to obtain sockets to communicate with that
remote registry. java.rmi.server.ObjID
The Java 2 platform has introduced a new property java.rmi.server.randomIDs,
which, if set to true, ensures that an ObjID (contained in a remote object reference) contains a cryptographically secure random number. The property defaults to false. If the
property is set to true, you will experience several seconds of delay when the first
ObjID is generated while the secure random number generator determines its seed. java.rmi.server.RMIClassLoader
The RMIClassLoader class contains two new methods: getClassAnnotation and
a loadClass method that takes a codebase path and a class name as arguments. The
getClassAnnotation method returns a string containing the class’s codebase path.
RMI transmits the codebase path along with the class descriptor when marshalling an
instance of that class in a parameter, return value, or exception for a remote call. The
new loadClass method was added to load a class from a codebase path, which is a
string of URLs separated by spaces. java.rmi.server.RMISocketFactory
The RMISocketFactory class now implements
java.rmi.server.RMIClientSocketFactory and
6 of 32
Remote Method Invocation Overview java.rmi.server.UnicastRemoteObject
The UnicastRemoteObject class has several new constructors, exportObject
methods, and a new unexportObject method. The constructors and exportObject
methods have been added to use java.rmi.server.RMIClientSocketFactory
and java.rmi.server.RMIServerSocketFactory objects as arguments. The two
new forms of the exportObject method return a Remote object instead of a
RemoteStub object since the former allows more flexibility in future implementations
of RMI. java.rmi.server.useLocalHostname Property
RMI now uses an IP address for the local host if the java.rmi.server.hostname
property is not specified and a fully qualified domain name for the localhost cannot
be obtained. In order to force RMI to default to the hostname, you need to set the
java.rmi.server.useLocalHostname property to true. The useLocalHostname
property defaults to false.
Change to the URL Codebase
A codebase can now be a list of URLs separated by ASCII space characters. Each URL
in turn will be used in an attempt to locate class files. The process is similar to the use of
Note: This enhancement is incompatible with RMI in the JDK 1.1.x versions.
New Stubs and No Skeletons
The Java 2 platform’s version of the rmic command supports the option -v1.2, which
allows for a smaller footprint and remote interface evolution.
1.4 Localization and Internationalization
The rmic, rmid, and rmiregistry programs use property files (via
java.util.ResourceBundle) to load the messages which are displayed on the
The tags supplied to ResourceBundle.getBundle are, respectively,
sun.rmi.rmic.resources.rmic, sun.rmi.rmid.resources.rmid, and
sun.rmi.registry.resources.rmiregistry. The default property files are in
JAVA_HOME/jre/lib/rt.jar (for rmid and rmiregistry) and
JAVA_HOME/lib/tools.jar (for rmic) jar files in the distribution.
rmic was internationalized in JDK 1.1. rmid has been internationalized since it was
introduced in Java 2 version 1.2. The rmiregistry program was not internationalized
until version 1.2.2 of the Java 2 platform. As of Java 2 version 1.3, all three programs
have been localized to the Japanese (JA) and Chinese (ZH) locales.
The detailed text of exceptions and errors thrown by RMI are not internationalized. (It’s
not clear that this would make sense anyway, since the exception text may be travelling
to a different locale.)
7 of 32
Product Distribution
2.0 Product Distribution
RMI is part of the Java core, and is available with the Java 2 platform release and the
Java Plug-in.
3.0 Requirements and Dependencies
3.1 System Requirements and Dependencies
Each system used for development must have enough disk space to install the Java 2
platform and enough free memory to run Java programs.
Each system that will run RMI code must have the following:
• A TCP/IP protocol stack and at least one IP-capable network interface
• A naming service (such as DNS or NIS) which is used by the class methods, which in turn use the socket functions
gethostbyname and gethostbyaddr
Each system that will export RMI objects must have the following:
• A permanent IP address or a permanent hostname; in this context, “permanent”
means that the address or hostname must remain valid over the lifetime of the
exported objects
• A permanent IP address/hostname that is reachable or resolvable by all hosts using
the exported objects
3.2 Software Requirements and Dependencies
Product Dependencies
Each Java VM which will run rmid must have a Runtime.exec(String[]) method
• Is fully implemented and supported: In particular, it must not simply throw
SecurityException or UnsupportedOperationException
• Operates asynchronously, that is: returns to its caller in a timely fashion without
waiting for the newly-spawned process to run to completion
• Interprets the first element of the parameter array as a command name
• Recognizes the specific string formed by System.getProperty(java.home) +
File.separator + bin + File.separator + java as the command name to
run a Java VM (for example, if java.home is /java and File.separator is / ,
this value would be /java/bin/java)
• Interprets subsequent -D options as the java command does (that is, as instructions
to assign system properties)
• Interprets one of the arguments not beginning with - as a class name whose
method is to be called (much as the java command does)
8 of 32
Requirements and Dependencies
The reference implementation for the Solaris™ operating environment and related
Win32 implementation satisfy all of the above constraints on the Runtime.exec
Other Software Requirements
JVMs exporting RMI servers may require higher-than-default resource limits for their
use of file descriptors and file handles. The Java API provides no access to this systemspecific control, so resource modifications must be done by the invoker of the Java VM.
Typically, RMI servers are started by a shell script. In the Solaris operating environment, the script should use the Bourne shell ulimit command to raise the
RLIMIT_NOFILES resource limit to its maximum (typically 1024).
For example:
prompt> ulimit -n 1024
prompt> $JAVA_HOME/bin/rmiregistry &
prompt> $JAVA_HOME/java [-Dfirst_property] ... [-Dlast_property]
Alternatively, the script could use the C shell limit command to raise the resource
limit to its maximum:
prompt> limit descriptors 1024
Note that in some cases root access to the system is required in order for these commands to be effective.
Default Permanent IP Address
The value returned by is computed
early in the VM’s lifetime, and is expected to return the “permanent IP address” referred
to in Section 3.1, “System Requirements and Dependencies.” Typically, this is the IP
address of the host’s primary IP-capable interface, in dotted-quad format.
If the expression’s value is not the correct permanent name/address for the host, then
one of the system properties java.rmi.server.hostname or
java.rmi.server.useLocalHostName must be set, so that the default mechanism
will be overridden.
3.3 Product Limitations
Hosts with multiple IP interfaces must either choose a single IP address which is reachable from all clients, or choose a single hostname which is resolvable to a reachable
address by all clients.
Hosts whose only reachable IP addresses are dynamically assigned must either obtain a
permanent host name which is dynamically bound to the current IP address, or be prepared to stop and restart Java VMs that export objects every time the address changes.
The complexity of object graphs which are marshalled as part of RMI calls is limited by
the stack size of a Java thread due to the recursive implementation of serialization.
9 of 32
Requirements and Dependencies
Prior to version 1.3 of the Java 2 platform, strings passed in remote method calls were
limited to a UCS Transformation Format 8 (UTF-8) representation of 65,535 bytes. Version 1.3 introduced a new string format which allows transmission of arbitrarily long
strings. See Section 1.2.1, “Serialization Enhancements (Notably for RMI).”
3.4 Product Compatibility
Interoperability With Existing Sun and Third-Party Software
Network Information Service (NIS) works as a replacement name service for Domain
Name System (DNS). However, when using Windows NT with Solstice™ and NFS™
(Sun’s distributed computing file system), listing NIS before DNS in the
nameservice preference list may cause occasional spurious
Internet Inter-Orb Protocol
RMI over IIOP now exists as a separate set of packages which is also distributed with
the Java 2 platform (starting with version 1.3). A separate support readiness document
which covers RMI-IIOP exclusively will be posted to by December, 2000.
Hypertext Transfer Protocol
RMI loads class files using any URL protocol that the Java platform supports, including
HTTP, FTP, and file, by making use of the URLClassLoader class. With the Java 2
platform, classes can be loaded from jar files; prior to the Java 2 platform, codebase
URLs could only refer to directories.
Previous Versions
• JDK 1.0.2 – There was a pre-beta version of RMI that was not bundled with the
• JDK 1.1 – RMI is included as part of the core JDK.
Java 2 Platform
The core RMI is enhanced in the Java 2 platform to include the features discussed in
Section 1.0, “Remote Method Invocation Overview,” such as downloadable socket factories and object activation. In addition, support was added for jar files and the new Java
2 platform security features. See Section 1.2, “New in the Java 2 Platform, Version 1.3”
for a discussion of new features added for version 1.3 of the Java 2 platform.
Backward/Forward Compatibility With Other Versions
Version 1.0.2
The exportObject method of UnicastRemoteObject did not return a
RemoteStub object, so it is incompatible with subsequent releases.
10 of 32
Version 1.1
The hostname-lookup cache in 1.1 did not have a cachelookup policy. Hosts which had permanent host names but dynamically-assigned IP
addresses would be unreachable from JDK 1.1 callers following an IP address update,
because the InetAddress cache of the caller would never update or invalidate its old
binding for the hostname.
JDK 1.1 virtual machines can use remote objects which have been exported from the
Java 2 platform JVMs and vice versa. However, 1.1 JVMs are not able to use or export
activatable objects or remote objects with downloadable socket factories, because those
APIs are only available in the Java 2 platform.
The change in security model between JDK 1.1 and the Java 2 platform is important for
RMI programs, mainly because it disables security privileges for CLASSPATH classes
when a security manager is installed.
Codebases which consist of multiple URLs will be unusable by JDK 1.1 peers.
Stubs created by supplying the -v1.2 option to the rmic command are not usable by
JDK 1.1 JVMs.
Version 1.2
Applications running in a 1.2 (or earlier) version of the Java platform are not able to
deserialize “long” strings written by a 1.3 JVM (where “long” indicates a string whose
UTF encoding exceeds 65,535 bytes in length). An attempt to deserialize a long string
will result in a StreamCorruptedException being thrown. For additional information, see Section 1.2.1, “Serialization Enhancements (Notably for RMI).”
Version 1.3
Due to a change in the java.rmi.activation.ActivationGroupDesc.getClassName
method (see Section 1.2.2, “RMI Enhancements”), RMI applications that register activatable objects and are running in a 1.3 JVM must register the objects with a 1.3 version
of rmid.
4.0 Configuration
4.1 General Configuration
In addition to CLASSPATH and system-specific resource limits (see the discussion on file
descriptor limits in Section 3.2.2, “Other Software Requirements”), RMI depends upon
the following:
• A security policy – The security policy for the server (and possibly client) JVM
should be put into a policy file and set from the command line, like any other property, as in the following example:
prompt> java
The rmiregistry requires a security policy (set with -J-D...) only if remote
objects with downloadable socket factories are bound in the registry.
11 of 32
• An HTTP server – The classes needed by clients should be made available on an
HTTP server and referenced using a URL. This requirement has not changed since
JDK 1.1, except that codebase URLs can now refer to jar files. There are many
HTTP servers available; a simple one which is pure Java and distributed by Sun
Microsystems™ with source is available at the following FTP site:
Note: An HTTP server is only required if classes are loaded by referencing HTTP
URLs. If your RMI client and server communicate using FTP or file URLs, an
HTTP server is not required.
• A hostname – If the default behavior of the getHostAddress method (see
Section 3.2.3, “Default Permanent IP Address”) is not appropriate for use by all clients, the system property java.rmi.server.hostname should be set to the
desired permanent hostname or IP address. As a convenience, the system property
java.rmi.server.useLocalHostName can be set to true and the hostname
will be initialized from the configured hostname of the host.
4.2 Configuration for Use With a Firewall
RMI is occasionally expected to operate over firewalls. For more information, see:
4.3 Configuration for Use With Signed Jar Files
If a developer wishes to use signed jar files as a means of safely granting extra privileges
to dynamically-loaded classes, the keystores will have to be initialized ahead of time
with the possible signing keys. There is no public-key infrastructure defined by Java yet.
To view the tutorial on the Java 2 platform security and signing JAR files, see:
4.4 RMI Properties
The following subsections describe all RMI-related system properties, including both a
complete list of the properties specified by the RMI public API and a list of useful properties understood by Sun’s RMI implementation.
Properties that begin with java.rmi. are elements of public specification: they are
also documented in the RMI specification.
Properties that begin with sun.rmi. are only supported by certain versions of the Sun
implementation of the JDK or Java 2 Standard Edition (J2SE). While these sun.rmi.*
properties can be quite useful for debugging and runtime tuning, please note that they
are not considered part of the public Java API in any sense, and their interpretation is
subject to change (or may be removed completely) in future versions of the implementation.
The number listed after each property name denotes the version of the Java platform in
which the given property was introduced.
12 of 32
java.rmi Properties
• java.rmi.activation.activator.class (1.2-): the name of the implementation class that the activation system should use to instantiate the
java.rmi.activation.Activator remote object. The default value is
• java.rmi.activation.port (1.2-): TCP port on which the activation system
(rmid) will listen for incoming remote calls. The default value is 1098.
• java.rmi.dgc.leaseValue (1.1-): the duration in milliseconds of leases issued
by this VM to other VMs which hold remote references to objects in this VM. Clients usually renew the lease when it is 50% expired, so a very short value will
increase network traffic and risk late renewals in exchange for reduced
Unreferenced.unreferenced() latency. The default value is 600,000 ms (10
• java.rmi.server.codebase (1.1-): URL string (or space-separated list of
URLs in 1.2 and beyond) that will be the codebase annotation for all classes loaded
from CLASSPATH and subsequently marshalled by this VM.
• java.rmi.server.disableHttp (1.1-): if true, disables HTTP-tunneling even
when http.proxyHost is set.
• java.rmi.server.hostname (1.1-): hostname string which should accompany
remote stubs for locally-created remote objects to enable clients to invoke methods
on the remote object. In 1.1.7 and beyond, the default value is the IP address of the
local host, in “dotted-quad” format.
• java.rmi.server.logCalls (1.1-): if true, logs incoming calls and exceptions
thrown from incoming calls to System.err.
• java.rmi.server.randomIDs (1.1.8-): if true, causes object identifiers for
remote objects exported in this VM to be generated using a cryptographically secure
random number generator. The default value is false.
• java.rmi.server.useCodebaseOnly (1.1-): if true, inhibits automatic
loading of classes from locations other than the CLASSPATH and the value of the
local java.rmi.server.codebase property. This property is ignored in the
implementations of 1.2 and 1.2.1 due to a bug.
• java.rmi.server.useLocalHostname (1.1.7-): RMI now uses an IP address
to identify the local host if the java.rmi.server.hostname property is not
specified and a fully qualified domain name for the localhost cannot be obtained.
In order to force RMI to default to the hostname, you need to set the this property to
sun.rmi Properties
In the following list, the properties named *.logLevel support the values SILENT,
BRIEF, and VERBOSE, which are case-insensitive and may be abbreviated. Logging is
done to System.err. All of them default to SILENT. Where a property is said to output
to the transport log (for instance), it enables logging to a LogStream returned by
java.rmi.server.LogStream.log(transport), which by default goes to System.err unless explicitly set to something else.
13 of 32
• sun.rmi.activation.execTimeout (1.2-): time in milliseconds that the activation system will wait for a spawned activation group to start up. The default value is
30,000 ms (30 seconds).
• sun.rmi.activation.snapshotInterval (1.2-): controls the number of
updates for which the activation system will wait before it serializes a snapshot of its
state to the rmid log file on disk. An “update” refers to a persistent change in the
state of the activation system (for example, registration of an activatable object). The
value of this property is a positive integer value. The default value is 200.
• sun.rmi.dgc.checkInterval (1.1-): the length of the interval in milliseconds at
which RMI checks for expired DGC leases. The default value is 300,000 ms (5 minutes).
• sun.rmi.dgc.cleanInterval (1.1-): maximum length of time that RMI will
wait before retrying a failed DGC clean call. The default value is 180,000 ms
(3 minutes).
• sun.rmi.dgc.client.gcInterval (1.2-): maximum interval in milliseconds
that RMI will allow between garbage collections of the local heap, in order to ensure
that DGC clean calls for unreachable remote references are delivered in a timely
fashion. The default value is 60,000 ms (60 seconds).
• sun.rmi.dgc.logLevel (1.1-): logs incoming and outgoing calls related to DGC
lease granting, renewing, and expiration. Outputs to the dgc log.
• sun.rmi.dgc.server.gcInterval (1.2-): maximum interval in milliseconds
that RMI will allow between garbage collections of the local heap, in order to ensure
that unreachable remote objects are unexported and garbage collected in a timely
fashion. The default value is 60,000 ms (60 seconds).
• sun.rmi.loader.logLevel (1.2-): logs class name and codebase whenever
RMI attempts to load a class as a result of unmarshalling an argument or return
value. Outputs to the loader log.
• sun.rmi.log.debug (1.2-): if true, details of rmid’s ReliableLog activity get
printed to System.err.
• sun.rmi.rmid.maxstartgroup (1.2-): the maximum number of activation
group VMs that rmid will allow to be in the “spawning but not yet active” state
simultaneously. If more VMs need to be started, they will queue until one of the current spawn attempts either succeeds or times out. The default value is 3.
Note that this does not limit the maximum number of active VMs; it is intended to
smooth out sudden spikes of activity to avoid reaching OS limits.
• sun.rmi.server.activation.debugExec (1.2-): cause the activation system
to print out the command line used for spawned activation groups. If true, prints
the command line, otherwise doesn’t print. The default value is false.
• sun.rmi.server.exceptionTrace (1.2-): this property will control the output
of server-side stack traces that are thrown from dispatched incoming remote calls. If
true, exception stack traces will be printed; if false (the default) they won’t be.
• sun.rmi.server.logLevel (1.1-): logs details of outgoing calls, including some
connection-reuse information. Outputs to the transport log.
14 of 32
Changes to the Command Tools
• sun.rmi.transport.connectionTimeout (1.1.6-): period in milliseconds for
which RMI connections may reside in an “unused” state before RMI will allow
those connections to be freed (closed). The default value is 15,000 ms (15 seconds).
• sun.rmi.transport.logLevel (1.1-): detailed logging throughout the transport
layer. Outputs to the transport log.
• sun.rmi.transport.proxy.connectTimeout(1.1-): maximum length of time
that RMI will wait for a connection attempt (createSocket) to complete, in milliseconds. The default value is 15,000 ms (15 seconds).
• sun.rmi.transport.proxy.logLevel (1.1-): logs events (createSocket
and createServerSocket) when the default RMISocketFactory is used.
Likely to be useful for applications that use RMI over HTTP. Events caused in a custom socket factory are not logged by the use of this property. Outputs some messages to the proxy log, and others to the transport log.
• sun.rmi.transport.tcp.localHostNameTimeOut (1.1.7-): the time in
milliseconds that the RMI runtime will wait to obtain a fully qualified domain
name for the local host. The default is 10,000 ms (10 seconds).
• sun.rmi.transport.tcp.logLevel (1.1-): provides detailed logging for the
TCP-specific transport sub-layer. Outputs to the tcp log.
• sun.rmi.transport.tcp.readTimeout (1.2.2-): the time in milliseconds
used as an idle timeout for incoming RMI/TCP connections. The value is passed to The default value is (2 * 3600 * 1000) ms
(2 hours).
5.0 Changes to the Command Tools
Each of the RMI commands (rmic, rmid, and rmiregistry) is included in the
JAVA_HOME/bin directory of the Java 2 platform. This section describes the changes to
each of those commands.
5.1 The RMI Compiler - rmic
New Options to rmic (Since Java 2 Version 1.3)
• Two new options, -idl and -iiop, have been added to generate IDL and stubs for
IIOP, respectively.
New Options to rmic (Since Java 2 Version 1.2)
The most significant change is that there is a family of new -v options to produce:
• Version 1.1 stubs that are fully compatible with JDK 1.1
• Java 2 platform stubs that are smaller and more flexible but incompatible with JDK
1.1 JVMs
• “Compat” stubs that use the Java 2 platform interface, if available, and the JDK 1.1
interface otherwise
Version 1.1 stubs are functionally identical to version 1.3 and 1.3 compat stubs.
15 of 32
Changes to the Command Tools
Reduced Constraints on the Remote Interfaces Handled by rmic
Prior to Java 2 version 1.2, a remote class declared as follows was illegal:
public class RI implements R { ... }
public interface R implements S, java.rmi.Remote { }
public interface S {
public void aMethod() throws java.rmi.RemoteException;
The JDK 1.1 rmic (before JDK 1.1.7) would reject the class RI because its interface R
extends a non-remote interface S. The Java 2 platform rmic accepts the class RI in spite
of this fact, as long as all of the methods declared in and inherited by R are declared to
throw RemoteException.
5.2 The RMI Activation Daemon - rmid
The rmid command, new to the Java 2 platform, launches the Activation Daemon (also
known as the “RMI daemon,” “activation,” or “activation system”). When run, rmid
establishes an RMI registry on port 1098 and binds the primary exported object available there to the name java.rmi.activation.ActivationSystem. The function
of rmid is to provide implementations for the Activator, ActivationMonitor, and
ActivationSystem: in other words, to automatically monitor and activate activatable
objects in their subprocess Java VMs.
Note that due to a change in the
java.rmi.activation.ActivationGroupDesc.getClassName method (see
Section 1.2.2, “RMI Enhancements”), RMI applications that register activatable objects
and are running in a 1.3 JVM must register the objects with a 1.3 version of rmid.
The rmid command uses a “log” directory to store information about registered objects
across reboots and other events. This log is read during startup and frequently updated
in a stable manner. Note that the format of the log entries changed incompatibly
between the Beta4 release of the Java 2 platform and the “First Customer Ship” (FCS)
release: The log directory should be cleared if an error is encountered when upgrading
from 1.2beta4 to the Java 2 platform FCS, and rmid should be restarted.
The rmid command can be run with the -stop option to initiate an orderly shutdown
of the activation daemon and its subprocesses. This is highly recommended on Win32 as
an alternative to killing the rmid process, because it first deactivates any subprocesses.
The -C option of rmid deserves some explanation. When rmid spawns a “child” VM to
host a java.rmi.activation.ActivationGroup, it runs a command of the general form:
java groupopts props rmidopts sun.rmi.server.ActivationGroupInit
where the following options are the arguments to java:
• groupopts represents the options specified in the
ActivationGroupDesc.CommandEnvironment structure, if there were any.
16 of 32
Administering RMI
• props is a sequence of -Dname=value strings representing the property overrides
for the group, also obtained from the CommandEnvironment structure.
• rmidopts is a sequence of strings each of which was preceded by -C on the rmid
command line.
6.0 Administering RMI
Generally, RMI servers (including rmid and rmiregistry) need to be stopped and
restarted when:
Class files are updated and need to be reloaded.
Network addresses are changed and there is no permanent name or address.
The server crashes.
Performance degradation occurs. Occasionally TCP connections can become stale
but never be reclaimed (in the event of some intermediate network failures). Some
Java Database Connectivity (JDBC™) drivers notoriously leak memory; multiplexed connections from JDK 1.0.2 clients can accumulate.
• Security policies or system properties need to be changed. Generally, system properties are examined once during initialization, and subsequent changes to them will
have no effect until the VM is restarted.
7.0 Bug Fixes
You can search for known bugs on the Java Developer Connection™ by using Bug
Parade. This online utility will enable you to locate both integrated and open RMI bugs.
From you can
search under the keywords “RMI” or “Remote Method Invocation.”
7.1 RMI Bugs Fixed in Java 2 Version 1.3
The following bugs were fixed in the Java 2 version 1.3 release of RMI. You can locate
a complete bug description for each of the following problems by searching Bug Parade
for the given bug number. Note that this list is not complete; other bugs were fixed for
1.3 as well, but were not considered relevant for inclusion here.
4268258 DGC should retry dirty calls before the lease expires.
Problem: RMI’s implementation of distributed garbage collection involves sending
“dirty” calls when remote references are passed between JVMs, to indicate
to the JVM exporting the remote object that other JVMs have obtained references to the object (so it should not be eligible for local garbage collection). In previous versions of RMI, the policy for retrying failed dirty calls
was not robust, and could lead to premature garbage collection of an
exported remote object if the network load was heavy.
17 of 32
Bug Fixes
The mechanism for retrying failed dirty calls has been improved, lessening
the likelihood of overzealous garbage collection due to intermittent network
4278457 Nonexistent skeleton class is sought for every remote object exported.
Problem: With 1.2 and subsequent versions of RMI, a remote implementation class
FooImpl no longer needs a corresponding skeleton class FooImpl_Skel
in order to export an instance, because the stub class can just use the -v1.2
stub protocol to communicate remote method invocations. However, prior
to version 1.3 the RMI implementation still searches for a corresponding
skeleton class every time a remote object is exported, in case the object’s
stub only uses the -v1.1 stub protocol. If no such skeleton class exists, this
step adds a significant overhead to the time required to export each instance,
because class loaders do not cache failures, so a filesystem or HTTP server
must be probed every time.
This problem was fixed by maintaining a cache of implementation classes
which have previously been found not to have corresponding skeleton
Unreferenced.unreferenced(...) threads should run in the
nonSystem group.
Prior to 1.3, RMI would invoke the java.rmi.server.Unreferenced.unreferenced callback method inside a thread belonging to the
system thread group. Consequently, if the callback method attempted to
modify its thread group, for example, by spawning new threads of its own, it
would require the RuntimePermissions modifyThreadGroup and
RMI now uses a thread that is not in the system thread group to execute the
callback, eliminating the need for the callback code to be granted the
aforementioned RuntimePermissions.
rmic sometimes fails to compile remote methods with inner class parameters.
In earlier versions of the Java 2 platform, rmic would in some cases fail to
generate correct stubs for classes with methods accepting inner class
The rmic bundled with Java 2 version 1.3 will generate proper stub code,
assuming that the class files the stub depends on have been compiled with
the javac also included in Java 2 version 1.3.
Minor problem with the way ReliableLog handles IOExceptions
When rmid is run in “unusual” circumstances, such as being stopped and
started many times and forced to make many log snapshots, a null pointer
exception can occur. Usually this problem occurs when the rmid logfile
is deleted while rmid is still running, or when a previous instance of rmid
is still running and keeping the log open.
18 of 32
Bug Fixes
rmid now attempts log recovery. If that fails, it shuts down gracefully. Clients have no chance of being duped into thinking rmid is running without
errors when it is unable to maintain persistent state (as was the case previously).
4221173 DGCAck not sent on connections using HttpSendSocket.
Problem: If RMI is making a call using HTTP, it may fail to send a distributed garbage collection acknowledgement upon completion of the call, causing any
remote objects passed as a return value of the call to be pinned unnecessarily in the VM that the remote call was made to.
RMI will now send the DGC acknowledgement properly, regardless of
whether the call is made over HTTP or not, resulting is less memory wastage.
4242317 rmiregistry annotates CLASSPATH classes with file: URLs, not
codebase property
Problem: When a class that can be found in the CLASSPATH of the rmiregistry
tool is marshalled via RMI, it is annotated with the list of file: URLs for the
actual elements of the CLASSPATH, rather than the value of the
java.rmi.server.codebase property. Classes loaded from CLASSPATH
(or, more precisely, the system class loader, the extension class loader, or
the bootstrap class loader) are supposed to be annotated only with the value
of the java.rmi.server.codebase property.
This problem means that the java.rmi.server.codebase property cannot be used to set the annotation that the rmiregistry should use for
classes in its CLASSPATH (although the recommended usage is not to place
application classes in an rmiregistry CLASSPATH anyway). It also
means that the structure of the file system on the host that the rmiregistry is executing on could be unintentionally exposed. And another problem
with this bug is that it can make execution of some distributed applications
in some situations succeed when they should fail: for example, the receiving
VM can read from the indicated file: URLs because it is on the same host as
the rmiregistry VM, or if the file system path happens to be network
accessible in some domain. These conditions would be more likely during
development or testing execution. This incorrect success can lead to unexpected failures when the distributed application is deployed to a larger network scope.
rmiregistry now properly annotates outgoing classes found in
CLASSPATH with the value of the java.rmi.server.codebase property.
4243264 rmid shutdown thread interferes with remote calls in progress.
Problem: One of the first actions of the rmid shutdown thread is to close the log. It is
possible for pending calls (such as activeObject) to be in progress, and
they will fail with a NullPointerException when they attempt to use
the log.
rmid now delays closing the log until pending calls have completed.
19 of 32
Bug Fixes
4254103 RemoteObject.toStub() return values cannot be .equals() with
unmarshalled stubs
Problem: The return value stubs of RemoteObject.toStub and
UnicastRemoteObject.exportObject (before they are ever unmarshalled) are not .equals() with different instances of stubs that correspond to the same remote objects. Because of this behavior, it is not
possible to use a HashTable to track the implementations of remote
objects. It is not possible to reference the table with an unmarshalled stub
(the stub will not be .equals() with its implementation).
Stubs to an object obtained via calls to RemoteObject.toStub or UnicaseRemoteObject.exportObject are now always .equals() to
other instances of stubs corresponding to the same remote object.
4259564 rmid’s usage message is incomplete and inconsistent with those of other
Problem: rmid’s usage message does not conform to the same format as the usage
messages of other J2SE SDK tools, and is missing some of the options that
rmid supports.
rmid’s usage message has been updated to be complete and consistent with
those of other J2SE SDK tools.
4208794 handleMessages should read() and not readByte() to avoid
Problem: When a client closes a TCP connection, the server will throw an EOFException in handleMessages, where it had been blocked in DataInputStream.readByte(). Although this is perfectly normal and to be
expected (the exception is caught and handled properly internally), it can
result in falsely alarming exception traces when debugging messages are
RMI now handles this case without throwing EOFExceptions.
20 of 32
Bug Fixes
7.2 RMI Bugs Fixed in Java 2 Version 1.2.2
4169311 The accept loop aborts on OutOfMemoryError.
Problem: The RMI code responsible for looping and accepting new incoming connections does not catch Errors or RuntimeExceptions. Consequently, if an
Error or RuntimeException (in particular, an OutOfMemoryError or
SecurityException) is thrown in the accept loop, the thread responsible
for listening on that particular socket will terminate.
The accept loop now catches and handles such exceptions/errors appropriately.
4174006 java.rmi.server.useCodebaseOnly property not recognized in
Problem: The value of the java.rmi.server.useCodebaseOnly property is
ignored. The code that purports to read the value of the property to implement its behavior instead reads the value of the
java.rmi.server.codebase property.
The java.rmi.server.useCodebaseOnly property is now read properly, and works as documented.
4211906 No codebase annotated for multi-dimensional array classes.
Problem: RMIClassLoader.getClassAnnotation() always returns null if the
supplied class is an array class whose element type is also an array class.
Thus, if the eventual non-array element type is a class, it will not be downloaded if necessary as expected when passed to a remote endpoint.
Multi-dimensional array classes are now annotated properly.
4179055 Some Java apps need to have permission
Problem: Applications using java.lang.SecurityManager or
java.rmi.RMISecurityManager must be granted the
RuntimePermission accessClassInPackage.sun.rmi.server in
order to call ActivationGroup.getSystem without getting an
Applications which call ActivationGroup.getSystem no longer need
to be granted the
RuntimePermission accessClassInPackage.sun.rmi.server.
21 of 32
Bug Fixes
4180392 RMI’s security manager and class loader do not enforce package access correctly.
Problem: The implementation of the checkPackageAccess method in
java.rmi.RMISecurityManager is, for historical reasons, derived from
the implementation in the internal applet security manager used by the
JDK’s appletviewer (sun.applet.AppletSecurity), so that it is supposed to restrict access to packages for which a property named
package.restrict.access.# (where # is the name of the package) is
defined to be true. Since the introduction of the 1.2 security model, a package foo must be listed in the security property package.access and
there must be a boolean property with the name defined to be true in order for package foo to be restricted in a VM where an instance of
RMISecurityManager is installed.
RMISecurityManager no longer defines its own
checkPackageAccess method, but uses the implementation inherited
from java.lang.SecurityManager instead. Thus, there is no need to
define any properties of the form package.restrict.access.#.
4182104 Threads created by Remote Method Implementations shouldn’t run as system threads.
Problem: When the RMI runtime uses reflection to make an “up call” to service a
remote method invocation, the thread in which the implementation method
for the call is executed will be an RMI system thread. As a result, any
user-supplied implementation method that needs to create a new thread will
require the RuntimePermissions modifyThreadGroup and
RMI now uses a thread that is not in the system thread group to execute the
method upcall, eliminating the need for the user code to be granted the
aforementioned RuntimePermissions.
4151966 rmiregistry error message obscure; internationalize rmiregistry.
Problem: rmiregistry does not have a full usage message, is not internationalized,
and may print equivocal error messages.
rmiregistry now has a full, internationalized usage message consistent
with other Java runtime utilities.
4203167 Accept thread stalls indefinitely on telnet-to-port.
Problem: If you telnet to a port on which an RMI accept thread is listening, and the
built-in socket factory is in use, and you don’t type anything, the accept
thread will be blocked in HttpAwareServerSocket.accept() indefinitely.
Kill the connection at the operating environment or network level, or restart
the VM.
22 of 32
Bug Fixes
4165495 registry’s checkAccess refuses clients from multi-homed hosts.
Problem: If you telnet to a port on which an RMI accept thread is listening, and the
built-in socket factory is in use, and you don’t type anything, the accept
thread will block indefinitely.
Code for recognizing HTTP-encapsulated method calls has been moved
from HttpAwareServerSocket into the thread-specific
ConnectionHandler, so that it cannot stall the accept thread.
4191926 RMI class loading has some non-intuitive permission behavior.
Problem: When a server is unmarshalling parameters to an RMI call, if a class
descriptor is encountered with a codebase that the server does not have
permission to connect to, the unmarshalling will fail with a
ClassNotFoundException (containing a security exception) even if the
class can be resolved by name through the server’s context class loader.
This problem can happen in simple RMI applet/server communication if the
server code does not have permission to connect to the codebase that the
applet gets loaded from, and the applet passes the server objects of some of
its own types found in its codebase. Those types will get annotated with the
applet’s codebase, and even though the server has them in its class path, it
will fail to resolve them because it doesn’t have permission to connect to
that extraneous codebase (if there wasn’t even a codebase annotation, it
would work fine). The workaround, in this case, of granting the server that
permission seems to be acceptable because the server and its associated
applet classes should be friendly with each other.
This problem has been fixed, so that in cases like the one mentioned above,
the server does not require extraneous permissions in order to resolve the
4183202 rmid and rmiregistry could allow alternate security manager.
Problem: Both rmid and rmiregistry set their security manager to be the
RMISecurityManager. This prevents an application from using its own
security manager in conjunction with either of these tools.
In both rmid and rmiregistry, a security manager will only be installed
if one has not already been set. Custom security managers can be used for
either tool by specifying<custom security
manager class name> on the command line.
4183204 Client-side multiplexing should be disabled.
Problem: The use of multiplexing to the client bypasses intended security checks. It
was initially introduced to allow callbacks to applets, which were otherwise
impossible to do because the Netscape browser’s security manager did not
allow applets to listen on a socket on an anonymous port.
Support for client-side multiplexing has been removed from RMI. Serverside multiplexing is still supported, for backward compatibility with earlier
releases that use client-side multiplexing.
23 of 32
Bug Fixes
4208795 The accept thread resolves client hostname before spawning connection
Problem: The accept thread names the connection-handler thread using the
toString method of the newly accepted socket’s InetAddress. Unfortunately, InetAddress.toString() can wait for an address-to-hostname
lookup, which can take an arbitrary amount of time to complete.
The accept thread now names the connection-handler thread with the host
address instead of the hostname.
4185842 rmic can’t find bootstrap classes if -classpath given.
Problem: Before 1.2, the -classpath option of both rmic and javac always overrode the entire search path used by the compiler to find source and binary
class files for compilation, regardless of whether they were application or
system classes. In 1.2, the javac -classpath option was split into
-bootclasspath (where the compiler would search for system class
files), -classpath (where the compiler would search for application files),
-extdirs (where the compiler should look for classes in installed extensions) and -sourcepath (where the compiler should search for application source files). Meanwhile, rmic retained the same 1.1 -classpath
rmic now treats -classpath the same as javac does, and also supports
the -bootclasspath, -extdirs and -sourcepath command line
7.3 RMI Bugs Fixed in Java 2 Version 1.2.1
Version 1.2.1 of the Java 2 platform was an interim version released specifically to
address security issues external to RMI. There were no changes to RMI in this release.
7.4 RMI Bugs Fixed in Java 2 Version 1.2.0
4008655 rmiregistry does not handle stub class evolution.
Problem: In JDK 1.1 the implementation of the java.rmi.registry.Registry
interface did not handle stub classes evolving over time. If a remote object
implementation added support for an additional interface after its previous
stub was loaded into the registry, object serialization would flag a class mismatch when binding the new stub in the registry.
This fix involved a change in the RMI stub protocol. Method hashes are
now used to indicate the implementation method to which a remote call
should be dispatched on an RMI server, and the operation field is used as a
flag for the new protocol (it is always -1).
24 of 32
Bug Fixes
40063565 Servers may not exit since distributed GC is not aggressive enough.
Problem: In JDK 1.1, applications (servers) that export remote objects might not exit
even if all remote objects had been garbage collected (remotely and locally)
and there were no other non-daemon threads in the process other than an
RMI thread which kept the process alive.
See the fix description for Bug 41071205 - RMI garbage collection could be
more timely. The new Java 2 platform weak reference API has solved this
Need to download socket factories for use with custom socket type.
Problem: It was not possible for clients to dynamically make use of a custom RMI
protocol (that is, have the code for the protocol downloaded to the client
on demand).
This problem was fixed by allowing applications to set custom client and
server socket factories on a per-remote-object basis. Client socket factories
are specified as part of an object’s remote reference type (using the new
UnicastRemoteObject constructors and exportObject methods).
As a result, when a reference to a remote object that uses custom socket factories is passed in a remote call to a new JVM, the class for the client socket
factory for that object will be downloaded dynamically into that JVM.
To view a tutorial that demonstrates how to use this mechanism, see
41071205 RMI garbage collection could be more timely.
Problem: Garbage collection of remote objects in RMI 1.1 only occurred under
extreme conditions.
RMI has used WeakReference objects to ensure more timely collection of
remote objects. A remote object will be disposed of without the VM having
to run low on system resources; for example, memory. The introduction of a
new reference API in the Java 2 platform, java.lang.ref.*, has enabled
RMI to cause remote objects to be collected in a more timely fashion. RMI
no longer has to rely on object finalizers to cause a “dirty call” to be sent to
a server JVM. DGC “dirty calls” are now invoked when a client drops its
strong references to a stub object.
40798125 Security: cached connections in RMI can be misused.
Problem: In JDK 1.1 (before JDK 1.1.6) it was possible for downloaded bytecodes
to obtain access to cached connections which those bytecodes did not
have permission to access.
Relevant permission checks have been added to RMI in the Java 2 platform
in order to close this security hole. Specifically, RMI’s connection reuse
mechanism now performs a security checkConnect before it will hand out
cached connections to downloaded code.
25 of 32
Using RMI
40948915 Activation: Unable to retry call if cached connection to server is used.
Problem: If the transport reuses a cached connection and the endpoint of the connection had previously failed, the call resulted in an UnmarshalException.
In the Java 2 platform, cached connections are tested for staleness if they
have been cached for more than a short time.
Note: Prior to this fix, cached connections to the rmiregistry could also
become corrupted if the process that was serving the registry was stopped
and restarted.
40103555 RemoteException should have server’s stack trace.
Problem: In JDK 1.1, when remote exceptions were serialized from an RMI server to
an RMI client, the transient stack trace of the exception would not be
For security reasons, it is advisable never to send the stack trace of an
exception over the wire. However, instead of throwing remote exceptions
that contain no stack trace, RMI now throws exceptions that contain the
client-side stack trace of a failed remote call.
8.0 Using RMI
Whereas this section discusses what problems socket factories and activation solve, the
tutorials on custom socket factories and activation give examples of how to use these
new features. To view the online tutorials, see: products/jdk/1.2/docs/guide/rmi/index.html.
8.1 Downloadable Client Socket Factories
Downloadable socket factories provide solutions to two problems: security and firewall
traversal. Socket factories also provide server administrators with a means of defining
how a prospective caller is to make contact with a server when a direct TCP connection
is not possible.
The Java 2 platform socket factory model can be easily adapted to tunnel RMI’s communication through a transport-layer security module such as SSL.
There are new UnicastRemoteObject.exportObject methods which accept a pair
of socket factories (one for the client and one for the server). The client socket factory
will be marshalled with the stub and unmarshalled on the client (if the client is a Java 2
platform implementation). The client will use the client socket factory when making
connections for the purposes of making RMI calls.
8.2 Activatable Objects
Activation is provided for the purpose of having persistent references which can survive
a reboot. Also, it is possible to register many activatable objects which will be inactive
most of the time, to reduce the demand on system resources.
26 of 32
Tuning and Troubleshooting
9.0 Tuning and Troubleshooting
9.1 Installation and Configuration Caveats
rmiregistry: CLASSPATH Without the Application’s Classes
A frequent error is to run rmiregistry (or rmid) with the application classes in
CLASSPATH. This misconfiguration results in the rmiregistry not being able to find
stub classes through the system ClassLoader. The result is that when stubs are
returned to clients from a call to the lookup method of java.rmi.Naming, the stubs
are marshalled with no codebase annotation at all, regardless of any codebase specified
by the server that called the bind or rebind method of class Naming.
The essential symptom of this misconfiguration is that a rebind call will succeed but a
call to lookup will throw a ClassNotFoundException embedded in an
File Descriptor Limit
On hosts running the Solaris operating environment, the default file descriptor limit is
64. Failure to issue the following command:
prompt> ulimit -n 1024
before starting the rmiregistry or other RMI server can limit the number of simultaneous clients to 60 or less. Note that ulimit is a shell built-in command; the corresponding /bin/csh command setting is:
prompt> limit descriptors 1024
Server IP Address
If the host’s default IP address (see Section 3.2.3, “Default Permanent IP Address”) is
inappropriate for use by clients, either because it is subject to change or because the host
is multi-homed and not all of its addresses are reachable, then the property
java.rmi.server.hostname should be used to set the permanent hostname when
starting RMI services. This property is not necessary when starting the RMI registry, but
rmid may require the property to be set using -J-D. In fact, use of
java.rmi.server.hostname is recommended if possible, because it eliminates the
uncertainty of which hostname or IP address is being used.
Security Policy Files
The new requirement for a security policy is a major change in the Java 2 platform, and
is likely to surprise RMI administrators who haven’t read the release notes. RMI programs that download code must have a security policy file that grants the minimal necessary permissions to the right codebases. Because this is seen as an inconvenience,
many users take shortcuts in order to “get it to work” first and figure out the security
The least protected security policy is:
grant {
27 of 32
Tuning and Troubleshooting
This is not recommended on production systems because it allows any downloaded code
to cause any damage it can, without restriction. A safer shortcut is to use the following
policy entry:
grant codeBase “file:/C:/app/” { permission
AllPermission; };
which only gives privileges (all privileges) to any code loaded from the local filesystem,
in this example the app directory on the C: drive. The codeBase’s granted permissions
should be URLs which correspond to directories in the CLASSPATH.
An even shorter shortcut is, for instance,
prompt> java -Xbootclasspath/p:$CLASSPATH StartSomeServer
which will prepend the entire CLASSPATH to the “boot class path,” that is, the privileged
system class path.
Note on codebase URLs used in policy files: There are several forms of file URLs being
used to refer to MS-DOS files/directories. If there is any doubt about the correct syntax
for use in a security policy file, it can be found by inspecting the output of a program
which is run with the java command flag:
prompt> java,failure
Specifying Codebase
Omitting the final `/’ from the value of a codebase URL (set by the
java.rmi.server.codebase property) will not work if it is meant to refer to a directory (as opposed to a jar file). Failure to set this properly will result in a
ClassNotFoundException during calls to the bind, rebind, and lookup methods.
ClassNotFoundException If Loading Classes From a Web Server
When an HTTP server is used to serve class files, it is important to have access to the
log files of that HTTP server, otherwise you may have a hard time debugging
ClassNotFoundExceptions due to missing files (usually superclasses and interfaces, and classes for field types).
9.2 Common User or System Administrator Errors
These errors are covered in the published RMI FAQ list. For more information, see
9.3 Common User Questions
First, see the FAQ referenced in Section 9.2, “Common User or System Administrator
One very common question is, “Why doesn’t RemoteException extend RuntimeException?”
Details on this explicit design decision can be found in the document, “A Note on Distributed Computing,” at:
28 of 32
Tuning and Troubleshooting
The subject was also discussed on the RMI-USERS list, at the following URL:
9.4 Error Message Guide
While not being a complete list, this will focus on the new and baffling common error
messages and exceptions which can be seen in the Java 2 platform.
group creation failed after 2 tries
This exception indicates that the activation daemon tried to spawn a subprocess to run
the selected group VM, but that the subprocess failed twice to contact the server within
30 seconds.
If the system property sun.rmi.server.activation.debugExec is set to true
when starting rmid, the actual command line will be written to System.err, which
may give a clue as to what is failing.
The problem might simply be that the subprocess takes longer than 30 seconds to start
up; in this case, set the sun.rmi.activation.execTimeout system property on
rmid to the number of milliseconds (default 30,000) for which RMI should wait for a
subprocess to report itself as active.
Note: sun.* properties are not official features of RMI, but are available in Sun’s
implementation on an unsupported release-to-release basis.
failed to activate object
This exception is thrown by the stub’s reference when a remote call to the activation
daemon fails, or when rmid is unable to activate the requested object. It could be a
transmission problem, or rmid might be temporarily unavailable, or rmid could have
failed to start the group in the way described above.
9.5 Known Bugs and Their Workarounds
The following list of known problems represents the bugs most likely to affect end-user
applications in version 1.3 of the Java 2 platform release of RMI. To locate the complete
bug descriptions for the following bugs by searching for the specific bug numbers, see:
Unicast remote object should be reachable from stub
RemoteObject.toStub returns.
Description: The stub object returned by the implementation of
RemoteObject.toStub in UnicastRemoteObject does not participate in the local or remote determination of the reachability of the server
object. Consider the following scenario:
29 of 32
Tuning and Troubleshooting
class FooImpl extends UnicastRemoteObject
implements Foo { ... }
Foo stub = (Foo) RemoteObject.toStub(new FooImpl());
After this line of code, the newly-created instance of FooImpl is not
considered reachable by either the local garbage collector (GC), because
the stub does not contain a strong reference (only an identifier) to the
server object, or the distributed GC (DCG). This particular stub will not
have been registered with the client side DGC.
Workaround:Do not depend on the reachability of a stub object returned from
RemoteObject.toStub to guarantee reachability of the remote server
object to which it refers; keep strong references to the server in the local
VM to ensure that the remote object does not get collected.
ActivationGroupImpl.newInstance does not set context
classloader for impl.
Description: ActivationGroupImpl.newInstance should set the context
classloader to the classloader of the activatable impl class before
calling the class constructor, but it doesn’t. As a result, if the constructor
attempts to download code, or creates threads that later attempt to download code, and the downloaded code needs to resolve classes that are in
the activatable object’s classloader but aren’t in the activation group’s
CLASSPATH, the class resolution will fail, or a class will be downloaded
instead of being found locally, usually resulting in a
Workaround:Explicitly set the context classloader on the current thread at the
beginning of the constructor.
9.6 Troubleshooting Utilities
The most generally useful debugging aid is to set the system property
java.rmi.server.logCalls=true. If it is set, then all incoming RMI calls, including DGC calls, cause a line to be printed indicating the target type, method, and ObjID.
More importantly, it causes exceptions and errors thrown in server methods to be
printed to the same stream.
Relating RMI References to Host Names and Port Numbers
To get the information about which hostname the stub is using, call the stub’s
toString method.
Codebase Debugging
If there is a problem loading necessary classes from a remote host, then setting the
sun.rmi.loader.logLevel=verbose will cause information about where the VM
is looking for the class to be printed.
Strategic Printing of Program State
The API call java.lang.Thread.dumpStack prints a stack trace of the current
30 of 32
Tuning and Troubleshooting
Running a Backtrace
To generate the backtraces of all threads in running in a given VM, perform the following steps:
1. Go to the shell or window where you entered the java command.
2. Make sure the shell or window has the keyboard focus and that the interpreter (java
command) isn’t a background process.
3. Enter the appropriate character:
Control-\ or kill -QUIT (Solaris)
Control-Break (Win32)
Text should be displayed in the window which will help you isolate the possible
For a good introduction on how to read a backtrace, see:
System Properties
RMI supports a comprehensive set of properties which enable user applications to modify the runtime behavior of RMI internals. Many users have found these properties to be
useful as debugging tools and as a means to fine-tune RMI functionality.
Properties named java.* are official; those named sun.* are unofficial and can
change or go away. Logging is done to System.err.
All of the properties are set by using the -D option to the java command. For example:
prompt> java -Djava.rmi.server.logCalls=true ServerMain
See Section 4.4, “RMI Properties,” for a more detailed description of properties.
9.7 Performance and Tuning Recommendations
The activation daemon, as shipped, has a default memory allocation of 8MB, which
causes it to immediately grow to 13MB. If rmid is started as in the following command,
it will start at 1MB and grow to 6MB:
prompt> rmid -J-Xms1m
The spawning of subprocesses within rmid is very time-dependent. In particular, if too
many subprocesses are started at the same time, none of them will be ready before the
timeout expires. Two properties control the rate of spawning of subprocesses,
sun.rmi.activation.execTimeout and sun.rmi.rmid.maxstartgroup:
• The system property sun.rmi.activation.execTimeout is the number of
milliseconds (default 30,000) for which the rmid VM will wait before giving up on
a subprocess.
• The system property sun.rmi.rmid.maxstartgroup is the maximum number
(default 3) of create-group requests that can be pending at one time.
31 of 32
Reference Information
10.0 Reference Information
10.1 Technical Documentation
Java Remote Method Invocation Specification
Starting Point for RMI Documentation
Additional Online Documentation
API Documentation
RMI Tutorials
10.2 Additional References
• The email list archives:
• The “Java Remote Method Invocation - Distributed Computing for Java” white
• The ”Java Remote Method Invocation” data sheet:
• “A Note on Distributed Computing”, November 1994:
• Java Object Serialization Specification:
32 of 32
Download PDF