[TOC] [Prev] [Next]

Marshaling Objects


The marshaling of arguments in remote calls and return values is performed by the object serialization technology developed for the Java language. It handles traversing graphs of objects and serializing the fields of each object, except for static and transient fields. Marshal streams extend the basic object serialization streams to specialize the behavior for remote objects. For more detail see the companion to the RMI Specification, the Java Object Serialization Specification.

Topics:

The ObjectOutputStream Class

The ObjectOutputStream class is used to serialize Java objects. It extends the functions of DataOutputStream to objects including arrays, Strings, and any class of Java object. The default mechanism for serializing objects is effective for marshaling most objects but in some cases specific objects may need or want to control how they are serialized. ObjectOutputStream calls a private method of the object to allow it to control its own serialized form.

package java.io;

public interface ObjectOutputStream
	extends DataOutputStream
	implements ObjectOutput
{
	public ObjectOutputStream(OutputStream out)
		throws IOException;

	public final void writeObject(Object obj)
		throws IOException;
}
An ObjectOutputStream is created using a constructor that specifies the stream to which the serialized objects and primitives are written. In the marshaling of objects the functions of DataOutputStream are used for primitive types and the writeObject method is used for Strings, arrays and objects.

The argument to writeObject method is an object to be serialized. The object may contain references to other objects. The serialization effectively recurses to serialize the complete graph of objects so that an equivalent graph can be reconstructed by ObjectInputStream. Each object is serialized by serializing each class in the superclass chain starting with Object and working down to the actual type.

A class may perform the serialization of its own fields by implementing a special method. If not defined, the default mechanism writes the fields of the object, except for transient and static fields, to the ObjectOutputStream using either the DataOutputStream methods for primitives or writeObject for objects. The special method can abort the serialization process by throwing an IOException. The NoAccessException should be used to signal that this class may not be serialized. The signature of the special method is:

    private void writeObject(ObjectOutputStream stream)
		throws NoAccessException;
Most classes will serialize themselves in the same way whether being marshaled or serialized to a file or buffer. If the class needs to have a different serialization for marshaling it can check the type of the stream using instanceOf. When marshaling for RMI the stream will be a MarshalOutputStream.

The ObjectInputStream Class

The ObjectInputStream is used to deserialize Java objects. It extends the functions of DataInputStream to objects including arrays, Strings, and any class of Java object. The default mechanism for deserializing object is effective for marshaling most objects but in some cases specific objects may need or want to control how they are deserialized. ObjectOutputStream calls a private method of the object to allow it extract its fields from deserialized form.

package java.io;

public class ObjectInputStream
	extends DataInputStream
	implements ObjectInput
{
	public ObjectInputStream(InputStream in)
		throws StreamCorruptedException, IOException;

	public Object readObject()
		throws ClassNotFoundException, IOException;
}
An ObjectInputStream is created using a constructor that specifies the stream from which the serialized objects and primitives are read. In the deserializing of objects the functions of DataInputStream are used for primitive types and the readObject method is called for Strings, arrays and objects.

The readObject method deserializes an object and returns it. The object may have contained references to other objects. The deserialization effectively recurses to deserialize the complete graph of objects so that an equivalent graph is reconstructed. Each object is deserialized by deserializing each class in the superclass chain starting with Object and working down to the actual type.

A class may perform the deserialization of its own fields by implementing a special method. If not defined, the default mechanism reads the fields of the object, except for transient and static fields, from the ObjectInputStream using either the DataInputStream methods for primitives or readObject for objects. The special method can abort the deserialization process by throwing an IOException. The NoAccessException should be used to signal that this class may not be deserialized, this should be implemented to insure that not even a concocted pickle could be used to create the object. The signature of the special method is:

    private void readObject(ObjectInputStream stream)
		throws NoAccessException;
Most classes will deserialize themselves in the same way whether being unmarshaled or deserialized from a file or buffer. If the class needs to have a different deserialization for unmarshaling it can check the type of the stream using instanceOf. When unmarshaling for RMI the stream will be a MarshalInputStream.

The MarshalOutputStream Class

A MarshalOutputStream extends ObjectOutputStream to add functions specific to marshaling of remote object references. If it is necessary to serialize remote objects or objects that contain references to remote objects a MarshalOutputStream must be used instead of ObjectOutputStream.

package java.rmi.server;

public class MarshalOutputStream
	extends ObjectOutputStream
	implements MarshalOutput
{
	public MarshalOutputStream(OutputStream out)
		throws IOException; 
}
A new MarshalOutputStream is constructed to serialize remote objects or graphs containing remote objects. Objects are written to the stream using the ObjectOutputStream.writeObject method.

MarshalOutputStream maps remote objects to the corresponding remote stub and embeds the location from which to load the stub classes. It location may be ignored by the client but is supplied.

The MarshalInputStream Class

MarshalInputStream is extended from ObjectInputStream to extract the location of stub classes to dynamically load and create stubs for remote objects. The location is used only if the stubs not available locally.

package java.rmi.server;

public class MarshalInputStream
	extends ObjectInputStream
	implements MarshalInput
{
	public MarshalInputStream(InputStream in)
		throws IOException, StreamCorruptedException;
}
A new MarshalInputStream should be created to deserialize remote objects or graphs containing remote objects. Objects are created from the stream using the ObjectInputStream.readObject method.

MarshalInputStream uses information embedded in the stream to locate and load stub classes, if those stubs are not available locally.



[TOC] [Prev] [Next]

rmi-comments@jse.East.Sun.COM
Copyright © 1996 Sun Microsystems, Inc. All rights reserved.