INTERNET-DRAFT V. Ryan Expires 16 June, 1999 S. Seligman R. Lee Sun Microsystems, Inc. 16 Dec, 1998 Schema for Representing Java(tm) Objects in an LDAP Directory Status of this Memo This document is an Internet-Draft. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." To view the entire list of current Internet-Drafts, please check the "1id-abstracts.txt" listing contained in the Internet-Drafts Shadow Directories on ftp.is.co.za (Africa), ftp.nordu.net (Northern Europe), ftp.nis.garr.it (Southern Europe), munnari.oz.au (Pacific Rim), ftp.ietf.org (US East Coast), or ftp.isi.edu (US West Coast). Abstract This document defines the schema for representing Java(tm) objects in an LDAP directory [LDAPv3]. It defines schema elements to represent a Java serialized object [Serial], a Java RMI remote object [RMI], and a JNDI reference [JNDI]. 1. Introduction This document assumes that the reader has a general understanding of the Java programming language [Java]. For brevity we use the term "Java object" in place of "object in the Java programming language" throughout this text. Traditionally, LDAP directories have been used to store data. Users and programmers think of the directory as a hierarchy of directory entries, each containing a set of attributes. You look up an entry from the directory and extract the attribute(s) of interest. For example, you can look up a person's telephone number from the directory. Alternatively, you can search the directory for entries with a particular set of attributes. For example, you can search for all persons in the directory with the surname "Smith". For applications written in the Java programming language, a kind of data that is typically shared are Java objects themselves. For such applications, it makes sense to be able to use the directory as a repository for Java objects. The directory provides a centrally administered, and possibly replicated, service for use by Java applications distributed across the network. For example, an application server may use the directory for "registering" objects representing the services that it manages, so that a client can later search the directory to locate those services as it needs. The motivation for this document is to define a common way for applications to store and retrieve Java objects from the directory. Using this common schema, any Java application that needs to read or store Java objects in the directory can do so in an interoperable way. 2 Representation of Java Objects This document defines schema elements to represent three types of Java objects: a Java serialized object, a Java RMI remote object, and a JNDI reference. 2.1 Common Representations A Java object is represented in the LDAP directory by the object class javaObject. This is the base class from which other Java object related classes derive: javaSerializedObject, javaRemoteObject, and javaNamingReference. javaObject is an abstract object class, which means a javaObject cannot exist in the directory; only auxiliary or structural subclasses of it can exist in the directory. The object class javaContainer represents a directory entry dedicated to storing a Java object. It is a structural object class. In cases where a subclass of javaObject is mixed in with another structural object class then javaContainer is not required. The definitions for the object classes javaObject and javaContainer are presented in Section 4. The javaObject class has one mandatory attribute (javaClassName) and one optional attribute (javaCodebase). javaClassName is used to store the fully qualified name of the object's Java class (e.g., "java.lang.String"). This may be the object's most derived class's name, but does not have to be. A superclass or interface in some cases might be most appropriate. javaCodebase is a multivalued attribute that is used to store the location(s) of the object's class definition. These attributes' definitions are presented in Section 3. 2.2 Serialized Objects To "serialize" an object means to convert its state into a byte stream in such a way that the byte stream can be reverted back into a copy of the object. A Java object is "serializable" if its class or any of its superclasses implements either the java.io.Serializable interface or its subinterface java.io.Externalizable. "Deserialization" is the process of converting the serialized form of an object back into a copy of the object. The Java platform specifies a default way by which serializable objects are serialized. A Java class can also override this default serialization and defines its own way of serializing objects of that class. [Serial] describes object serialization in detail. When an object is serialized, information that identifies its class is recorded in the serialized stream. However, the class's definition ("class file") itself is not recorded. It is the responsibility of the system that is deserializing the object to determine the mechanism to use for locating and loading the associated class definitions. For example, the Java application might include in its classpath a JAR file containing the class definitions of the serialized object, or load the class definitions using information from the directory, as explained below. 2.2.1 Representation in the Directory A serialized object is stored in the directory using the attributes javaClassName, javaCodebase, and javaSerializedData, as defined in Section 3. The mandatory attribute, javaSerializedData, contains the serialized form of the object. Although the serialized form already contains the class name, the mandatory javaClassName attribute also records the name so that the class name can be determined without having to perform deserialization. The optional javaCodebase attribute is used to store the locations of the class definitions needed to deserialize the serialized object. A directory entry containing a serialized object is represented by the object class javaSerializedObject, which is a subclass of javaObject. javaSerializedObject is an auxiliary object class, which means that it needs to be mixed in with a structural object class. javaSerializedObject's definition is given in Section 4. 2.3 Remote Objects The Java Remote Method Invocation (RMI) system [RMI] is a mechanism that enables an object on one Java virtual machine to invoke methods on an object in another Java virtual machine. Any object whose methods can be invoked in this way must implement the java.rmi.Remote interface. When such an object is invoked, its arguments are marshalled and sent from the local virtual machine to the remote one, where the arguments are unmarshalled and used. When the method terminates, the results are marshalled from the remote machine and sent to the caller's virtual machine. To make remote objects accessible to other virtual machines, the program that created them must register each such object with the "RMI registry." The program supplies to the RMI registry the string name of the remote object, and the remote object itself. When a program wants to access a remote object, it asks the RMI registry on the same machine as the remote object for a reference ("stub") to the remote object. The remote object is named using an "rmi" URL such as "rmi://hostname:port/remoteObjectName", where "hostname" and "port" identify the machine and port on which the RMI registry is running, and "remoteObjectName" is the string name of the remote object. If "remoteObjectName" is omitted, then the object being named is the RMI registry itself. When the program receives the stub for the remote object, it can invoke methods on the remote object (through the stub). See [RMI] for details. 2.3.1 Representation in the Directory A remote object is stored in the directory using the attributes javaClassName, javaCodebase, and javaRemoteObject, defined in Section 3. The mandatory attribute, javaRemoteLocation, contains the URL of the remote object. This is the string argument that is passed to the RMI registry when looking up the remote object. For example, a remote object registered under the name "AppRemoteObjectX" with the RMI registry on machine "rserver" might be stored in the directory with the javaRemoteLocation attribute value "rmi://rserver/AppRemoteObjectX". The mandatory javaClassName attribute is used to record the class name of the remote object. The optional javaCodebase attribute is used to store the locations of the remote object's class definition. A directory entry containing a remote object is represented by the object class javaRemoteObject, which is a subclass of javaObject. javaRemoteObject is an auxiliary object class, which means that it needs to be mixed in with a structural object class. javaRemoteObject's definition is given in Section 4. 2.4 JNDI References Java Naming and Directory Interface(tm) (JNDI) [JNDI] is a directory access API specified in the Java programming language. It provides an object-oriented view of the directory, allowing Java objects to be added to and retrieved from the directory without requiring the client to manage data representation issues. JNDI defines the notion of a "reference" for use when an object cannot be stored in the directory directly, or when it is inappropriate or undesirable to do so. An object with an associated reference is stored in the directory indirectly, by storing its reference instead. 2.4.1 Contents of a Reference A JNDI reference is a Java object of class javax.naming.Reference. It consists of an ordered list of addresses, and class information about the object being referenced. An address is a Java object of class javax.naming.RefAddr. Each address contains information on how to construct the object. A common use for JNDI references is to represent connections to a network service such as a database, directory, or file system. Each address may then identify a "communications endpoint" for that service, containing information on how to contact the service. Multiple addresses may arise for various reasons, such as replication or the object offering interfaces over more than one communication mechanism. A reference also contains information to assist in creating an instance of the object to which the reference refers. It contains the Java class name of that object, and the class name and location of the object factory to be used to create the object. The procedures for creating an object given its reference, and the reverse, are described in [JNDI]. 2.4.2 Representation in the Directory A JNDI reference is stored in the directory using the attributes javaClassName, javaCodebase, javaReferenceAddress, and javaFactory, defined in Section 3. These attributes store information corresponding to the contents of a reference described above. javaReferenceAddress is a multivalued optional attribute for storing reference addresses. javaFactory is the optional attribute for storing the object factory's fully qualified class name. The mandatory javaClassName attribute is used to record the class name of the object. The optional javaCodebase attribute is used to store the locations of the object factory's and the object's class definitions. A directory entry containing a JNDI reference is represented by the object class javaNamingReference, which is a subclass of javaObject. javaNamingReference is an auxiliary object class, which means that it needs to be mixed in with a structural object class. javaNamingReference's definition is given in Section 4. 2.5 Serialized Objects Vs. Remote Objects Vs. References Although all three object classes, javaSerializedObject, javaRemoteObject, and javaNamingReference, are used to represent Java objects, they do so storing different aspects of the Java objects. A javaRemoteObject and javaNamingReference provide a way of recording address information about an object which itself is not directly stored in the directory. For javaSerializedObject, (a copy of) the object is itself stored in the directory. In other words, you can think of a javaRemoteObject and javaNamingReference as compact representations of the information required to access the object, while a javaSerializedObject is the representation of the object itself. A javaNamingReference is a more general form of storing a reference to a Java object, while a javaRemoteObject is specifically for storing a reference to a Java RMI object. A javaRemoteObject and javaNamingReference typically consist of a small number of human-readable strings. Standard text-based tools for directory administration may therefore be used to add, read, or modify reference entries -- if so desired -- quite easily. Serialized objects are not intended to be read or manipulated directly by humans. 3 Attribute Type Definitions The following attribute types are defined in this document: javaClassName javaCodebase javaSerializedData javaRemoteLocation javaFactory javaReferenceAddress 3.1 javaClassName This attribute stores the Java object's fully qualified class or interface name (e.g. "java.lang.String"). This attribute's syntax is 'Directory String'. ( 1.3.6.1.4.1.42.2.27.4.1.1 NAME 'javaClassName' DESC 'Fully qualified Java class or interface name' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) 3.2 javaCodebase This attribute stores the Java class definition's locations. It specifies the locations from which to load the class definition for the class specified by the javaClassName attribute. It could be, for example, the URL of a JAR file (e.g., "http://webserver/appX/appx.jar"), or the URL of a file directory (e.g., "file:/pub/appXclasses/"). See [Java]. This attribute can have multiple values. When more than one value has been specified, each is tried until the class definition has been successfully loaded. This attribute's syntax is 'Directory String'. ( 1.3.6.1.4.1.42.2.27.4.1.6 NAME 'javaCodebase' DESC 'URL specifying the location of class definition' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) 3.3 javaSerializedData This attribute stores the serialized form of a Java object. The serialized form is described in [Serial]. This attribute's syntax is 'Binary'. ( 1.3.6.1.4.1.42.2.27.4.1.7 NAME 'javaSerializedData DESC 'Serialized form of a Java object' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE ) 3.4 javaRemoteLocation This attribute stores the location of the Java RMI remote object. It is the URL that must be supplied to the RMI registry for looking up the remote object. See [RMI]. This attribute's syntax is 'Directory String'. ( 1.3.6.1.4.1.42.2.27.4.1.8 NAME 'javaRemoteLocation' DESC 'Location of a Java RMI remote object' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) 3.5 javaFactory This attribute stores the fully qualified class name of the object factory (e.g. "com.wiz.jndi.WizObjectFactory") that can be used to create an instance of the object identified by the javaClassName attribute. This attribute's syntax is 'Directory String'. ( 1.3.6.1.4.1.42.2.27.4.1.4 NAME 'javaFactory' DESC 'Fully qualified Java class name of a JNDI object factory' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) 3.6 javaReferenceAddress This attribute represents the sequence of addresses of a JNDI reference. Each of its values represents one address, a Java object of type javax.naming.RefAddr. Its value is a concatenation of the address type and address contents, preceded by a sequence number (the order of addresses in a JNDI reference is significant). For example: #0#TypeA#ValA #1#TypeB#ValB #2#TypeC##rO0ABXNyABpq... In more detail, the value is encoded as follows: The delimiter is the first character of the value. For readability the character '#' is recommended when it is not otherwise used anywhere in the value, but any character may be used subject to restrictions given below. The first delimiter is followed by the sequence number. The sequence number of an address is its position in the JNDI reference, with the first address being numbered 0. It is represented by its shortest string form, in decimal notation. The sequence number is followed by a delimiter, then by the address type, and then by another delimiter. If the address is of Java class javax.naming.StringRefAddr, then this delimiter is followed by the value of the address contents (which is a string). Otherwise, this delimiter is followed immediately by another delimiter, and then by the Base64 encoding of the serialized form of the entire address. The delimiter may be any character other than a digit or a character contained in the address type. In addition, if the address contents is a string, the delimiter may not be the first character of that string. This attribute's syntax is 'Directory String'. It can contain multiple values. ( 1.3.6.1.4.1.42.2.27.4.1.3 NAME 'javaReferenceAddress' DESC 'Addresses associated with a JNDI Reference' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) 4 Object Class Definitions The following object classes are defined in this document: javaContainer javaObject javaSerializedObject javaRemoteObject javaNamingReference 4.1 javaContainer This structural object class represents a container for a Java object. ( 1.3.6.1.4.1.42.2.27.4.2.1 NAME 'javaContainer' DESC 'Container for a Java object' SUP top STRUCTURAL MUST ( cn ) ) 4.2 javaObject This abstract object class represents a Java object. A javaObject cannot exist in the directory; only auxiliary or structural subclasses of it can exist in the directory. ( 1.3.6.1.4.1.42.2.27.4.2.4 NAME 'javaObject' DESC 'Java object representation' SUP top ABSTRACT MUST ( javaClassName ) MAY ( javaCodebase ) ) 4.3 javaSerializedObject This auxiliary object class represents a Java serialized object. It must be mixed in with a structural object class. ( 1.3.6.1.4.1.42.2.27.4.2.5 NAME 'javaSerializedObject' DESC 'Java serialized object' SUP javaObject AUXILIARY MUST ( javaSerializedData ) ) 4.4 javaRemoteObject This auxiliary object class represents a Java RMI remote object. It must be mixed in with a structural object class. ( 1.3.6.1.4.1.42.2.27.4.2.6 NAME 'javaRemoteObject' DESC 'Java RMI remote object' SUP javaObject AUXILIARY MUST ( javaRemoteLocation ) ) 4.5 javaNamingReference This auxiliary object class represents a JNDI reference. It must be mixed in with a structural object class. ( 1.3.6.1.4.1.42.2.27.4.2.7 NAME 'javaNamingReference' DESC 'JNDI reference' SUP javaObject AUXILIARY MAY ( javaReferenceAddress $ javaFactory ) ) 5. Security Considerations Serializing an object and storing it into the directory enables (a copy of) the object to be examined and used outside the environment in which it was originally created. The directory entry containing the serialized object could be read and modified within the constraints imposed by the access control mechanisms of the directory. If an object contains sensitive information or information that could be misused outside of the context in which it was created, the object should not be stored in the directory. For more details on security issues relating to serialization in general, see [Serial]. 6. References [Java] Ken Arnold and James Gosling, "The Java(tm) Programming Language", Second Edition, ISBN 0-201-31006-6. [JNDI] The Java(tm) Naming and Directory Interface (tm) Specification, JavaSoft Division, Sun Microsystems, Inc., Feb 1998. http://java.sun.com/products/jndi/. [LDAPv3] M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access Protocol (v3)" RFC2251, December 1997. [RMI] Remote Method Invocation, Java Software, Sun Microsystems, Inc., November 1998. http://java.sun.com/products/jdk/1.2/docs/guide/rmi [Serial] Object Serialization Specification, Java Software, Sun Microsystems, Inc., November 1998. http://java.sun.com/products/jdk/1.2/docs/guide/serialization 7. Authors' Addresses Vincent Ryan Sun Microsystems, Inc. Mail Stop EDUB03 901 San Antonio Road Palo Alto, CA 94303 USA +353 1 819 9151 vincent.ryan@ireland.sun.com Scott Seligman Sun Microsystems, Inc. Mail Stop UCUP02-209 901 San Antonio Road Palo Alto, CA 94303 USA +1 408 863 3222 scott.seligman@eng.sun.com Rosanna Lee Sun Microsystems, Inc. Mail Stop UCUP02-206 901 San Antonio Road Palo Alto, CA 94303 USA +1 408 863 3221 rosanna.lee@eng.sun.com