Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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 U.S.A. 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 U.S.A. Table of Contents Table of Contents Preface iv 1.0 Remote Method Invocation Overview 1 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 2 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 2 4 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 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 1.3.5.1 Remote Interfaces 5 1.3.5.2 Remote Exceptions 5 1.3.6 API Changes 6 1.3.6.1 java.rmi.RMISecurityManager 6 1.3.6.2 java.rmi.registry.LocateRegistry 6 1.3.6.3 java.rmi.server.ObjID 6 1.3.6.4 java.rmi.server.RMIClassLoader 6 1.3.6.5 java.rmi.server.RMISocketFactory 6 1.3.6.6 java.rmi.server.UnicastRemoteObject 7 1.3.6.7 java.rmi.server.useLocalHostname Property 1.3.7 Change to the URL Codebase 7 1.3.8 New Stubs and No Skeletons 7 7 1.4 Localization and Internationalization 7 2.0 Product Distribution 8 3.0 Requirements and Dependencies 8 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 3.4.1.1 Internet Inter-Orb Protocol 10 3.4.1.2 Hypertext Transfer Protocol 10 3.4.2 Versions 10 SUN MICROSYSTEMS, INC. 10 i Table of Contents 3.4.2.1 Previous Versions 10 3.4.2.2 Java 2 Platform 10 3.4.3 Backward/Forward Compatibility With Other Versions 3.4.3.1 Version 1.0.2 10 3.4.3.2 Version 1.1 11 3.4.3.3 Version 1.2 11 3.4.3.4 Version 1.3 11 4.0 Configuration 4.1 4.2 4.3 4.4 10 11 General Configuration 11 Configuration for Use With a Firewall 12 Configuration for Use With Signed Jar Files RMI Properties 12 12 4.4.1 java.rmi Properties 13 4.4.2 sun.rmi Properties 13 5.0 Changes to the Command Tools 15 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 7.1 7.2 7.3 7.4 17 17 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 26 8.1 Downloadable Client Socket Factories 8.2 Activatable Objects 26 9.0 Tuning and Troubleshooting 27 9.1 Installation and Configuration Caveats 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 26 27 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 28 9.2 Common User or System Administrator Errors 28 9.3 Common User Questions 28 9.4 Error Message Guide 29 SUN MICROSYSTEMS, INC. ii Table of Contents 9.5 Known Bugs and Their Workarounds 9.6 Troubleshooting Utilities 30 9.6.1 9.6.2 9.6.3 9.6.4 9.6.5 29 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 30 9.7 Performance and Tuning Recommendations 31 10.0 Reference Information 32 10.1 Technical Documentation 10.1.1 10.1.2 10.1.3 10.1.4 10.1.5 10.1.6 32 Java Remote Method Invocation Specification 32 Starting Point for RMI Documentation 32 RMI FAQ 32 Additional Online Documentation 32 API Documentation 32 RMI Tutorials 32 10.2 Additional References 32 SUN MICROSYSTEMS, INC. iii Preface 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 jsdt-1.4.zip -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 http://java.sun.com. Although the blue SUN MICROSYSTEMS, INC. iv Preface 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 jsdt://stard:5555/socket/Session/chatSession. • 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. SUN MICROSYSTEMS, INC. v 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 http://access1.sun.com/SRDs/access1_srds.html 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: SUN MICROSYSTEMS, INC. 1 of 32 Remote Method Invocation Overview 1.1.1 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 1.1.2 Packages • • • • • 1.1.3 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 superclass • java.rmi.activation.Activatable – a convenient activatable-object superclass • 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 JVM • java.rmi.server.RMIClassLoader – the classloader used by RMI • java.rmi.server.RMIClientSocketFactory – for per-object invocation connections • java.rmi.server.RMIServerSocketFactory – for per-object connection acceptance • java.rmi.server.RMISocketFactory – for per-VM socket factories 1.2 New in the Java 2 Platform, Version 1.3 1.2.1 Serialization Enhancements (Notably for RMI) Prior to 1.3, an attempt to serialize a string longer than 64K would result in a java.io.UTFDataFormatException 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- SUN MICROSYSTEMS, INC. 2 of 32 Remote Method Invocation Overview ten from a 1.3-compatible JVM, the 1.2 (or earlier) JVM will receive a java.io.StreamCorruptedException. 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. 1.2.2 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 java.io.NotSerializableException. 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: http://www.iso.ch/cate/d18741.html. SUN MICROSYSTEMS, INC. 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: http://java.sun.com/products/jdk/javadoc/. 1.2.3 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 factories. 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. 1.3.1 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 java.rmi.server.RMIServerSocketFactory. 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. SUN MICROSYSTEMS, INC. 4 of 32 Remote Method Invocation Overview 1.3.2 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 java.rmi.server.UnicastRemoteObject. A new daemon, rmid, has been added to facilitate object activation. The URLs to the rmid manual pages are: http://java.sun.com/products/jdk/1.2/docs/tooldocs/win32/ rmid.html and http://java.sun.com/products/jdk/1.2/docs/tooldocs/solaris/ rmid.html. 1.3.3 New Options to the rmic Command -J Options beginning with -J are passed to the Java interpreter after removing -J. This option is commonly used in conjunction with the -D option. -vcompat (default) Creates stubs and skeletons compatible with both the JDK 1.1 and the Java 2 platform stub protocol versions. -v1.1 Create stubs and skeletons for the JDK 1.1 stub protocol version. -v1.2 Create stubs for the Java 2 platform stub protocol version only. -O Has been removed from the manual page because it is no longer recommended for use. To view the rmic man pages, see: http://java.sun.com/products/jdk/1.2/docs/tooldocs/win32/ rmic.html and http://java.sun.com/products/jdk/1.2/docs/tooldocs/solaris/ rmic.html. 1.3.4 Changes Since JDK 1.1.x For information on additional changes, see http://java.sun.com/products/jdk/1.2/docs/guide/rmi/relnotes.html. 1.3.5 1.3.5.1 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 1.3.5.2, “Remote Exceptions.” 1.3.5.2 Remote Exceptions A remote interface method can alternatively use any of the superclasses of java.rmi.RemoteException, such as java.io.IOException or SUN MICROSYSTEMS, INC. 5 of 32 Remote Method Invocation Overview java.lang.Exception, instead of RemoteException in the throws clause of the method. 1.3.6 API Changes 1.3.6.1 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. 1.3.6.2 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. 1.3.6.3 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. 1.3.6.4 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. 1.3.6.5 java.rmi.server.RMISocketFactory The RMISocketFactory class now implements java.rmi.server.RMIClientSocketFactory and java.rmi.server.RMIServerSocketFactory. SUN MICROSYSTEMS, INC. 6 of 32 Remote Method Invocation Overview 1.3.6.6 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. 1.3.6.7 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. 1.3.7 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 CLASSPATH. Note: This enhancement is incompatible with RMI in the JDK 1.1.x versions. 1.3.8 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 screen. 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.) SUN MICROSYSTEMS, INC. 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 java.net.InetAddress 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 3.2.1 Product Dependencies Each Java VM which will run rmid must have a Runtime.exec(String[]) method that: • 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 main method is to be called (much as the java command does) SUN MICROSYSTEMS, INC. 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 method. 3.2.2 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] my.package.StartSomeServer 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. 3.2.3 Default Permanent IP Address The value returned by java.net.InetAddress.getLocalHost().getHostAddress() 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. SUN MICROSYSTEMS, INC. 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 3.4.1 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 UnknownHostExceptions. 3.4.1.1 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 http://access1.sun.com/SRDs/access1_srds.html by December, 2000. 3.4.1.2 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. 3.4.2 3.4.2.1 Versions Previous Versions • JDK 1.0.2 – There was a pre-beta version of RMI that was not bundled with the JDK. • JDK 1.1 – RMI is included as part of the core JDK. 3.4.2.2 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. 3.4.3 3.4.3.1 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. SUN MICROSYSTEMS, INC. 10 of 32 Configuration 3.4.3.2 Version 1.1 The java.net.InetAddress 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. 3.4.3.3 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).” 3.4.3.4 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 -Djava.security.policy=absolute_path_to_policy_file The rmiregistry requires a security policy (set with -J-D...) only if remote objects with downloadable socket factories are bound in the registry. SUN MICROSYSTEMS, INC. 11 of 32 Configuration • 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: ftp://ftp.javasoft.com/pub/jdk1.1/rmi/class-server.zip. 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: http://java.sun.com/products/jdk/rmi/faq.html#firewall. 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: http://java.sun.com/docs/books/tutorial/security1.2/index.html. 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. SUN MICROSYSTEMS, INC. 12 of 32 Configuration 4.4.1 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 sun.rmi.server.Activation$ActivatorImpl. • 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 minutes). • 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 true. 4.4.2 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. SUN MICROSYSTEMS, INC. 13 of 32 Configuration • 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. SUN MICROSYSTEMS, INC. 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 java.net.Socket.setSoTimeout. 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 5.1.1 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. 5.1.2 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. SUN MICROSYSTEMS, INC. 15 of 32 Changes to the Command Tools 5.1.3 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. 5.2.1 Logging 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. 5.2.2 Options 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. SUN MICROSYSTEMS, INC. 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 http://developer.javasoft.com/developer/bugParade/ 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. SUN MICROSYSTEMS, INC. 17 of 32 Bug Fixes Fix: The mechanism for retrying failed dirty calls has been improved, lessening the likelihood of overzealous garbage collection due to intermittent network failures. 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. Fix: 4214123 Problem: Fix: 4217967 Problem: Fix: 4183169 Problem: This problem was fixed by maintaining a cache of implementation classes which have previously been found not to have corresponding skeleton classes. 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 modifyThread. 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 parameters. 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. SUN MICROSYSTEMS, INC. 18 of 32 Bug Fixes Fix: 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. Fix: 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. Fix: 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. Fix: rmid now delays closing the log until pending calls have completed. SUN MICROSYSTEMS, INC. 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). Fix: 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 tools. 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. Fix: 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 EOFException. 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 enabled. Fix: RMI now handles this case without throwing EOFExceptions. SUN MICROSYSTEMS, INC. 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. Fix: The accept loop now catches and handles such exceptions/errors appropriately. 4174006 java.rmi.server.useCodebaseOnly property not recognized in 1.2fcs. 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. Fix: 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. Fix: Multi-dimensional array classes are now annotated properly. 4179055 Some Java apps need to have permission accessClassInPackage.sun.rmi.server. 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 AccessControlException. Fix: Applications which call ActivationGroup.getSystem no longer need to be granted the RuntimePermission accessClassInPackage.sun.rmi.server. SUN MICROSYSTEMS, INC. 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 package.restrict.access.foo defined to be true in order for package foo to be restricted in a VM where an instance of RMISecurityManager is installed. Fix: 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 modifyThread. Fix: 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. Fix: 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. Fix: Kill the connection at the operating environment or network level, or restart the VM. SUN MICROSYSTEMS, INC. 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. Fix: 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. Fix: 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 class. 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. Fix: 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 -Djava.security.manager=<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. Fix: 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. SUN MICROSYSTEMS, INC. 23 of 32 Bug Fixes 4208795 The accept thread resolves client hostname before spawning connection handler. 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. Fix: 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 semantics. Fix: rmic now treats -classpath the same as javac does, and also supports the -bootclasspath, -extdirs and -sourcepath command line options. 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. Fix: 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). SUN MICROSYSTEMS, INC. 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. Fix: 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 problem. RFE Need to download socket factories for use with custom socket type. 41278265 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). Fix: 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 http://java.sun.com/products/jdk/1.2/docs/guide/rmi/ rmisocketfactory.doc.html. 41071205 RMI garbage collection could be more timely. Problem: Garbage collection of remote objects in RMI 1.1 only occurred under extreme conditions. Fix: 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. Fix: 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. SUN MICROSYSTEMS, INC. 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. Fix: 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 retained. Fix: 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: http://java.sun.com/ 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. SUN MICROSYSTEMS, INC. 26 of 32 Tuning and Troubleshooting 9.0 Tuning and Troubleshooting 9.1 Installation and Configuration Caveats 9.1.1 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 UnmarshalException. 9.1.2 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 9.1.3 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. 9.1.4 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 later. The least protected security policy is: grant { permission java.security.AllPermission; SUN MICROSYSTEMS, INC. }; 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 java.security. 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 -Djava.security.debug=access,failure 9.1.5 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. 9.1.6 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 http://java.sun.com/products/jdk/rmi/faq.html. 9.3 Common User Questions First, see the FAQ referenced in Section 9.2, “Common User or System Administrator Errors”. 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: http://www.sunlabs.com/techrep/1994/abstract-29.html. SUN MICROSYSTEMS, INC. 28 of 32 Tuning and Troubleshooting The subject was also discussed on the RMI-USERS list, at the following URL: http://java.sun.com/products/jdk/rmi/archives/3490.html. 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. java.rmi.activation.ActivationException 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. java.rmi.activation.ActivateFailedException 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: http://developer.javasoft.com/developer/bugParade/. 4114579 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: SUN MICROSYSTEMS, INC. 29 of 32 Tuning and Troubleshooting interfaceFooextendsRemote{...} 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. 4289544 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 ClassCastException. 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. 9.6.1 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. 9.6.2 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. 9.6.3 Strategic Printing of Program State The API call java.lang.Thread.dumpStack prints a stack trace of the current thread. SUN MICROSYSTEMS, INC. 30 of 32 Tuning and Troubleshooting 9.6.4 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 problems. For a good introduction on how to read a backtrace, see: http://developer.java.sun.com/developer/technicalArticles/ Programming/Stacktrace/index.html. 9.6.5 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. SUN MICROSYSTEMS, INC. 31 of 32 Reference Information 10.0 Reference Information 10.1 Technical Documentation 10.1.1 Java Remote Method Invocation Specification http://java.sun.com/products/jdk/1.2/docs/guide/rmi/spec/ rmiTOC.doc.html 10.1.2 Starting Point for RMI Documentation http://java.sun.com/products/jdk/rmi/index.html 10.1.3 RMI FAQ http://java.sun.com/products/jdk/rmi/faq.html 10.1.4 Additional Online Documentation http://java.sun.com/products/jdk/1.2/docs/guide/rmi/ 10.1.5 API Documentation http://java.sun.com/products/jdk/1.2/docs/api/java/rmi/packagesummary.html 10.1.6 RMI Tutorials http://java.sun.com/docs/books/tutorial/rmi/index.html http://java.sun.com/products/jdk/1.2/docs/guide/rmi/ getstart.doc.html http://java.sun.com/products/jdk/1.2/docs/guide/rmi/ rmisocketfactory.doc.html http://java.sun.com/products/jdk/1.2/docs/guide/rmi/ activation.html 10.2 Additional References • The [email protected] email list archives: http://archives.java.sun.com/archives/rmi-users.html • The “Java Remote Method Invocation - Distributed Computing for Java” white paper: http://java.sun.com/marketing/collateral/javarmi.html • The ”Java Remote Method Invocation” data sheet: http://java.sun.com/marketing/collateral/rmi_ds.html • “A Note on Distributed Computing”, November 1994: http://www.sunlabs.com/techrep/1994/abstract-29.html • Java Object Serialization Specification: http://java.sun.com/products/jdk/1.2/docs/guide/serialization/spec/serialTOC.doc.html SUN MICROSYSTEMS, INC. 32 of 32