A portion of the disclosure of this patent document contains material to which a claim of copyright protection is made. The copyright owner has no objection to the facsimile reproduction by anyone of the patent document or the patent disclosure, as it appears in the Patent and Trademark Office patent file or records, but reserves all other rights whatsoever.
1. Field of the Invention
The present invention relates to computer programming, and deals more particularly with techniques for serializing objects (such as Java™ objects), and deserializing those objects, in a manner that enables contents of the objects to be preserved following changes to definitions of the object structures.
2. Description of the Related Art
For data transfer in distributed computing environments, as well as for storing data persistently, it becomes necessary to convert data structures between object format and serialized format. For example, such structured objects may be used when writing programs in the Java™ programming language. (“Java” is a trademark of Sun Microsystems, Inc.) The term “serialization” is used in the art to describe the process of taking an object and transforming it to a “flattened” data structure so that, for example, the contents of the object can be persistently stored or can be passed over a network connection in a serial or stream format. “Deserialization” then refers to the reverse process, whereby a flattened data structure is converted into object format.
Changes in class definitions are a typical occurrence when a new version of a software product is being created. The changes may correct errors that have been discovered in an earlier version, or new features may be added to the software product which necessitate revising the class definitions. Since newer versions of a product may contain changes to classes whose objects have been previously serialized, migration of the previously-serialized objects is generally necessary when a customer upgrades to a newer version of the product.
Several prior art migration techniques are known for performing migration of objects. Each of the known techniques suffers from drawbacks, however. Three migration techniques of the prior art will now be described, and difficulties encountered with each technique will also be described.
In a first approach, which is suitable for moderate changes to class definitions, Java serialization extensions provide some accommodation to handle new and changed attributes to objects that were serialized using standard Java serialization. However, this approach does not easily allow for more drastic changes, such as a restructuring of the class hierarchy or the changing of class names. It also does not easily provide direct access to the attributes of the previously-serialized object, which may be needed to construct the new object.
Another prior art approach for migration of objects is the use of a migration tool that reads each old object from storage, in turn, into an instantiation of the original class. An object according to the new class definition is then constructed from each old object. A major drawback of this solution is that it requires the old and new class definitions to be included with the product in order to perform the migration. Also, the migration process becomes complicated when the old and new classes have the same name.
A third prior art approach for migration of objects is to bypass Java serialization altogether, and store the object's attributes directly using getters and setters. A major drawback of this solution is that it requires the implementation of getters and setters in each class. A programmer needs to write code to save and restore the state of each serializable class, and must continually perform maintenance on the code as the class definition changes. Thus, this approach is time consuming, cumbersome, and error prone (and therefore expensive).
As an alternative to migrating the previously-serialized objects, users of the software product in which class definitions have changed might be required to simply eliminate all of those serialized objects and start anew to create objects using the new class definitions. For example, when serialized objects represent outstanding transactions of some type, a requirement to complete all of the transactions before upgrading to the new software might be imposed. However, this is a burdensome approach in most situations, and is therefore undesirable.
Accordingly, what is needed are techniques that enable programmatic migration of serialized objects following changes to definitions of the object structures, such that existing serialized objects are preserved, while avoiding drawbacks of prior art techniques.
An object of the present invention is to define techniques for programmatically migrating serialized objects following changes to definitions of the object structures.
Another object of the present invention is to provide programmatic version migration techniques which do not require products to include back-level versions of the classes for objects to be migrated.
Still another object of the present invention is to provide techniques that enable existing serialized objects to be preserved following changes to definitions of the object structures.
Yet another object of the present invention is to provide programmatic version migration techniques which enable programmer access to individual object attributes.
Still another object of the present invention is to provide programmatic migration techniques which enable automatic notification (such as exception generation) if migration software has not been provided for objects having a changed definition.
Other objects and advantages of the present invention will be set forth in part in the description and in the drawings which follow and, in part, will be obvious from the description or may be learned by practice of the invention.
To achieve the foregoing objects, and in accordance with the purpose of the invention as broadly described herein, the present invention provides improved methods, systems, and computer program products that enable programmatic migration of serialized objects. In one embodiment, the present invention comprises: serializing software objects by creating, for an object to be serialized to a persistent store, a graph structure comprising nodes that embody serializable attributes and values thereof; and writing the graph structure to the persistent store as a markup language document. The markup language document may be encoded, for example, in Extensible Markup Language (“XML”) notation. Preferably, the nodes are written as markup language elements in the markup language document and reflect a structure of the object (e.g., in hierarchical relationships among the markup language elements) according to one or more class definitions to which the object adheres. The attribute values are preferably reflected in attributes of the markup language elements. A new instance of the object may be created by deserializing the markup language document.
In another embodiment, the present invention provides techniques for enabling serialized objects to be preserved following changes to one or more class definitions used in those objects, comprising: creating, for an object to be serialized to a persistent store, a graph structure comprising nodes that embody a structure of the object and values of serializable attributes of the object; writing the graph structure to the persistent store, such that serializable information from one or more original class definitions to which the object adheres is persistently captured; programmatically determining, in order to deserialize the persistently captured information to a new instance of the object, whether serializable attribute definitions for the original class definitions, as reflected in the graph structure, are identical to serializable attribute definitions of one or more current class definitions to which the new instance must adhere; and deserializing the new instance of the object directly from the serializable information persistently captured within the graph structure, if the programmatic determination has a positive result, and performing a programmatic migration of the attribute values from the serializable information persistently captured with the graph structure otherwise. Preferably, the graph structure is written to the persistent store as a markup language document. Performing the programmatic migration may further comprise directly accessing individual attribute values from the persistently-captured serializable information.
In yet another embodiment, the present invention provides techniques for deserializing software objects, comprising: creating, from a markup language document written to a persistent store, a corresponding graph structure, wherein elements of the markup language document and nodes of the corresponding graph structure embody serializable attributes and values of an object and wherein the markup language document reflects one or more original class definitions to which the object adhered when the markup language document was created; and deserializing a new instance of the object from the graph structure.
In another embodiment, the present invention provides a data structure for enabling serialized objects to be preserved following changes to one or more class definitions used in those objects, the data structure embodied on a computer-readable medium and comprising a specification of a structure of an object according to one or more class definitions to which the object adheres and values of serializable attributes of the object, according to the one or more class definitions, such that the data structure is usable for deserializing a new instance of the object according to one or more current class definitions to which the new instance must adhere. Preferably, the specification of the serialized object comprises a markup language document representation.
The present invention will now be described with reference to the following drawings, in which like reference numbers denote the same element throughout.
The present invention defines novel techniques for serializing objects, and deserializing those objects, in a manner that enables contents of the objects to be preserved following changes to definitions of the object structures. Objects are serialized in a novel manner, and deserialization of those serialized objects is achieved in a novel manner. The disclosed techniques enable efficient programmatic migration of serialized objects after a new version of an object's class definition is deployed. Preferred embodiments are described herein with reference to serialized objects created in, and used by, Java software products. The disclosed techniques may, however, be adapted for use with other programming languages, and thus references to Java serialization are by way of illustration and not of limitation.
A model is defined for saving and restoring the state of an object, and regardless of the changes that may have been made to the object's class definition, this model allows objects that have been saved to persistent storage in serialized form to be efficiently migrated to the new version of the class definition.
In preferred embodiments, the model disclosed herein replaces the services of standard Java serialization with XML serialization. This model gives the programmer direct access to the contents of a serialized object's attributes, which are sometimes necessary to migrate the serialized object to the new class definition. As a result of using XML serialization as disclosed herein, instead of standardization techniques of the prior art, the present invention provides a mechanism for real-time migration of the serialized object (and enables effectively extending the serialization process, as contrasted to the prior art). This real-time migration is illustrated in the scenario depicted in
After each object has been migrated, this one-time migration performed during deserialization no longer occurs. In this example, the only additional code the programmer writes is the code to update the new and changed fields in Widget2-Redesigned. Other than that, serialization and deserialization of all objects are handled completely by components referred to herein as an XML serialization engine and an XML deserialization engine. A brief description of these engines will now be provided, after which more detailed discussions follow. (Note that while these are described as separate components, this is for illustrative purposes. An implementation of the present invention may choose to combine serialization and deserialization functions into a single component.)
According to techniques of preferred embodiments, the serialization of an object is performed by an XML serialization engine that uses Java reflection to recursively read the attribute names and values of each object and its references. The class and attribute information is subsequently serialized as (i.e., stored in) a markup language document which, by way of illustration but not of limitation, is referred to herein as an XML document. This new serialization model is depicted in
Deserialization of an object, according to techniques of preferred embodiments, is performed in two steps by an XML deserialization engine as disclosed herein. This new deserialization model is depicted in
The deserialization engine of preferred embodiments performs what is referred to herein as “best effort’ attempt at restoring attribute values from serialized objects. In other words, attributes whose names and types have not been changed are restored automatically. However, attributes that have changed are skipped by the engine, making it the programmer's responsibility to provide class-specific code to restore new and changed attributes. Preferably, a serial version identifier of a serialized object is used to determine whether the object's class definition has changed (as will be described in more detail below). If a class has changed, then custom code written by the programmer to address these changes is invoked by the deserialization engine. According to preferred embodiments, this custom code is placed inside the new class definition. (Examples are described with reference to
During deserialization, the custom code is invoked to handle the migration of the new and changed attributes. Since the deserialization engine provides the programmer direct access to every attribute in the old class definition (via the XML document in which the object was serialized and the SerializedObject graph in which the old class definition is reflected), the new object may be constructed from the ground up using the attributes from the old object. Thus, this model provides a mechanism for the preservation of serialized objects across different versions of a software product, allowing for the most extreme forms of object transformation.
Referring again to
As shown in
The XML data format is well suited for storing data that is hierarchical in nature, and can be adapted for storing information that is object-oriented, such as the object formats described herein. In
An overview of the serialization techniques of preferred embodiments will now be described. (Corresponding deserialization techniques will then be described.) As shown in
The root class 800, SerializedObject, contains attributes that are common to all objects, such as the name and className attributes. Although the root class cannot be instantiated (because it is an abstract class), the derived classes 810-850, which represent specific object types, may be constructed into a heterogeneous graph. Using this approach, every serializable object can be represented using a heterogeneous graph comprising instances of the derived classes. The purpose of each derived class, according to preferred embodiments, is summarized below:
Preferred embodiments use a “Serialized Object Model”, or “SOM”, which is defined herein as a heterogeneous graph comprising instances of the instantiable SerializedObject classes. As an example, a sample Java class Employee 920 is defined in
As illustrated in
Embodiments of the present invention are adapted for creating the SOM graph for an arbitrary class definition, using the approach shown in the example of
Finally, the XML document (from which objects are subsequently deserialized, according to the present invention) is generated by sending the DOM graph to an XML generator to write the DOM graph as an XML document. An example XML document, corresponding to the DOM graph 1100 in
In summary, the serialization is performed by creating the SOM graph, converting it to an XML DOM graph, and sending it to an XML generator for creation of an XML document. In preferred embodiments, the XML DOM graph may be generated directly from the object, avoiding the need to create the intermediary SOM graph. However, during deserialization, the creation of the SOM graph will be necessary so that partial deserialization capability can be provided (as discussed in more detail with reference to
The serialization and deserialization of a Java object will now be described in more detail with reference to the example shown in
In this example, serializing the Employee object 1310 (which was given the name “bill” when it was defined at reference number 930) recursively serializes the attributes in the Person and Employee classes to create the SOM graph having UserObject 1305 as its root. (In the sample code in
Because direct access to serialized attributes is provided by preferred embodiments, as noted with reference to the title attribute at 1360 and 1365, the programmer can include migration code that accesses the serialized attributes to update the corresponding class attributes if desired. (An example of updating an attribute value is depicted at reference number 2780 of
In order to serialize an object, the names and values of the attributes in an object need to be read. During this process, the SOM graph (or DOM graph, when the SOM graph is bypassed) can be constructed using these names and values. A preferred embodiment of the manner in which the present invention performs the serialization is shown in
When the serialization engine 1405 of preferred embodiments is invoked to serialize an object 1400, the object is sent 1410 to the serializer 1415 which in turn recursively reads the public, private, and protected attributes of the object using the Java Reflection API 1420. In order to read the private and protected attributes, the Security Manager 1430 is typically invoked 1425 to validate permissions. According to preferred embodiments, appropriate modifications are made to the security policy file to grant the serialization engine the necessary permissions (such as allowing access checks to be suppressed, which may be accomplished be granting the permission suppressAccessChecks when using the Java Security Manager) to read these privileged attributes. (If there is no Security Manager registered, then Security Manager 1430 and its invocations, as well as the granting of permissions, may be omitted.)
When the object's attributes are returned 1435, the serializer 1415 then constructs an XML DOM graph from those attributes (as illustrated in
Note that when serializing an object, the serializer preferably observes the rules established by the standard Java serializer regarding the treatment of transient, static, and other non-serializable attributes and classes. (For example, the standard Java serializer does not serialize a number of things, such as classes which do not implement the Serializable interface, static attributes, and so forth. Preferred embodiments preferably employ an analogous approach when serializing objects to XML documents.)
When deserializing an object, the attributes in the object need to be intialized, and migration of some attributes may be necessary if the object's class definition has been changed. A preferred embodiment of the manner in which the present invention performs the deserialization is shown in
Deserialization begins by opening an input stream 1560 on an XML document, enabling an XML parser 1550 to parse elements of XML data 1555 contained therein. These parsed elements 1545 (represented as a DOM graph, in preferred embodiments) are delivered to the deserialization engine 1505, which is responsible for deserializing the corresponding object 1500. The deserialization engine 1505 preferably sends 1540 this DOM graph representation (see, for example, DOM graph 1100 in
Note that when deserializing an object, the deserializer preferably observes the rules established by the standard Java deserializer regarding the treatment of transient, static, and other non-serializable attributes and classes. (Refer to the discussion above regarding those things which are not serialized by the standard Java serializer.)
In
The deserializer 1515 next invokes a module or entity referred to herein as Class Name Updater 1610 to update class names that have changed. In preferred embodiments, the deserialization engine allows the programmer to specify the class or interface which performs the updates, using (for example) helper methods provided by the SerializedObject class. For example, an invocation such as SerializedObject.changeClassName(oldName, newName) might be used, where the old and new class names are specified by the programmer as input parameters to the helper method. An example of invoking a class name change in this manner is provided at reference number 2750 in
The deserializer 1515 next creates an instance of the object using the class name specified in the root SOM node. An entity referred to herein as Object Creator 1615 will therefore create an object from the SerializedObject intermediary data structure. In order to instantiate a Java object, a constructor must be invoked. According to preferred embodiments, the object class preferably has either a public, private, or protected zero-argument constructor. Use of a zero-argument constructor enables the deserializer of preferred embodiments to programmatically invoke the constructor for an arbitrary class. Using the Java Reflection API 1420, the deserializer can therefore create an instance of the object using the privileged constructor (and as shown at 1640, the deserializer populates the object using the corresponding attribute values from the SOM graph).
It may happen, however, that a zero-argument constructor is not provided. See, for example, reference number 2730 of
Preferably, the object is verified to have a zero-argument constructor or instantiate successfully with null arguments before it is serialized, and if not, an exception is preferably thrown. This will ensure that notification of this issue arises before deserialization is attempted. In addition, when an object is being deserialized, if the class in the root SOM node cannot be loaded, an exception should be thrown. However, if a class in a child SOM node cannot be loaded, this may be handled by skipping the corresponding attribute, allowing the programmer to provide custom migration code for this situation.
After the object has been instantiated, the deserializer 1515 begins the process of initializing the object with the corresponding attribute values from the SOM graph. If the object implements an interface indicating it wishes to perform a custom import of the SOM graph, a method from that interface (such as customObjectImport( . . . )) may be invoked to perform the custom import. See, for example,
In preferred embodiments, use a of custom importer provides the programmer with access to methods for traversing and deserializing nodes in the SOM graph. Referring briefly to
In addition to, or instead of, invoking the custom importer for performing specific attribute migration, a default importer may be invoked. This default importer is illustrated at 1635 in
In preferred embodiments, the default importer works in the following manner. For each class in the SOM graph, it searches the object class hierarchy for the corresponding class. If the class is found, then the default importer recursively deserializes each child node (as illustrated at reference numbers 1325, 1335, 1365, and 1375 of
When a SOM class definition differs from the located object class definition, or there is not a one-to-one correspondence between the classes in the SOM graph and the serializable object classes, the deserializer preferably ensures that the programmer has acknowledged the difference by implementing the custom importer interface; otherwise, an exception is preferably thrown. Even if no custom code is necessary to migrate the object, the acknowledgement of the difference ensures that the programmer knows that not all attributes will be restored when the object is deserialized. As an alternative to providing a custom importer interface, the programmer may acknowledge the difference by implementing a flag interface. For example, suppose the new class definition includes one or more fields, such as revising the Person class illustrated in
Detection of a change in the class definition may be implemented by comparing the serial version identifier of the SOM class to the serial version identifier of the object's class. The serial version may be computed using just the serializable attributes in a class. This will ensure that changes to method signatures or to non-serializable attributes have no effect on the serial version of the class. The manner in which serial version identifiers are used in standard Java versioning support for detecting changes to a serialized object's class definition will now be described, followed by a discussion of how modifications may be made to those standard Java techniques for use with the present invention.
In the Java programming language, a built-in versioning technique for serialized objects is provided. Each serializable class may declare a variable “serialVersionUID” (hereinafter, “SUID”), which is a 64-bit long integer that will store a stream-unique identifier. Typically, the value of this variable is computed by hashing the class's signature—i.e., its name, interface class names, methods, and fields. (The details of this hashing algorithm are not pertinent to the present discussion, and will not be described in detail herein.) This standard Java versioning technique enables determining whether the class definition that a previously-serialized object conformed to when it was serialized is the same class definition currently available from the object class hierarchy. Stated in another way, if the SUID value is identical between a set of serialized objects, this is an indication that the objects share a common format for serialization and deserialization. If the SUID values do not match, then execution of standard Java deserialization to create an object using the current class definition is not allowed (thereby avoiding creation of a corrupted object).
For example, suppose the class definition for a serialized object is as shown in
On the other hand, preferred embodiments of the present invention preferably compute an SUID over only the serializable attributes of an object. Accordingly, the SUID comparison performed by preferred embodiments of the present invention detects incompatibility arising from change to serialized attributes. In one approach, the computation of SUIDs over the serializable attributes may be implemented by extending the existing Java versioning. As another approach, this modified computation of an SUID value may be carried out using logic which is newly-created for use with an implementation of the present invention.
As yet another approach, rather than using SUID values to detect incompatibility between a class definition and previously-serialized objects, a field-by-field comparison may be made between the SOM graph for a serialized object and the corresponding class definition for that object when a deserialization operation is being performed, thereby determining whether the class definition has changed.
Referring now to
The serialization and deserialization engines may be implemented as classes, in an analogous manner to Java's ObjectInputStream and ObjectOutputStream classes. Within these engines, the serializer and deserializer may be implemented as an interface which may be specified (when the engines are constructed) in a form such as new XMLObjectOutputStream(ostream, myCustomSerializer).
In the example shown in
Referring now to
For example, if the object being serialized is an array of java.lang.String, the SerializedObject 1830 invokes 1905 the static serialize( ) method in the ArrayObject class 1915. For each string in the array, the ArrayObject 1915 invokes the SerializedObject again, which in turn invokes the SpecialObject 1920 to serialize the string. Using this approach, the ArrayObject creates a DOM graph comprising a parent node and the child nodes returned from the SpecialObject. In this way, the entire DOM graph (returned at 1900 in
An object cache 1950 is preferably maintained to keep track of objects that have already been serialized. This ensures that the serializer does not recurse indefinitely when circular references (such as linked lists, which deliberately contain circular references such as next and previous) are encountered, and preferably establishes a reference number to identify each previously-serialized object. The reference number, which is stored in the DOM graph, may be used during deserialization to preserve commonality of references.
Support for serialization extensions is an optional aspect of the present invention. If support for Java serialization extensions is desired, the SpecialObject 1920 may invoke 1940 the appropriate extensions 1945 (such as writeObject( ), writeExternal( ), and so forth) when appropriate. In this case, the Java ObjectOutputStream class (see reference number 1960) is preferably extended and passed to the extension code 1945 to intercept the methods invoked by the extension code, in order to incorporate the extension data into the DOM graph of SpecialObject 1920. Note that there are many Java serialization extensions, of which writeObject( ) and writeExternal( ) are the most common. Depending on the nuances of particular extensions, it may not be possible in some cases to fully support emulation of the serialization extension using the techniques of preferred embodiments.
The DefaultXMLSerializer 1820 invokes 2050 the static createinstance( ) method in the SerializedObject class 1830 to convert the DOM graph to a SOM graph. The root node of the SOM graph will be one of the four derived classes (ie. PrimitiveObject, ArrayObject, SpecialObject, UserObject). After class names have been updated, if necessary (i.e., if class names have been changed), the DefaultXMLSerializer 1820 invokes 2060 the non-static deserialize( ) method at the root level of this SOM graph to perform a full deserialization of the object and its child objects (as discussed above with reference to
Referring now to
For example, if the object being deserialized is an array of java.lang.String, the DefaultXMLSerializer 1820 invokes 2100, 2105 the non-static deserialize( ) method in the ArrayObject class 1915. (Note that the deserialize( ) method is invoked directly on the appropriate derived class, as shown by reference numbers 2100, 2105.) For each child node in the SOM graph, the ArrayObject 1915 invokes its deserialize( ) method, which invokes the SpecialObject class 1920 to deserialize the string (as was discussed with reference to 1300 and 1325 of
An object cache 2120 is preferably maintained to keep track of objects that have already been deserialized, in an analogous manner to the object cache 1950 described with reference to
If the optional aspect providing support for Java serialization extensions is implemented, as discussed above with reference to
As explained earlier, if the object implements an interface indicating it wishes to perform a custom import of the SOM graph, the object is invoked to perform the custom import. The UserObject 1925 passed to the custom importer should provide the programmer with the methods that can be used to traverse and deserialize nodes in the SOM graph. The object may also invoke the default importer while performing the custom import. (Refer to the discussion of
Several source code implementation examples will now be described with reference to
In this example, the classes in
Sample code 2400 in
The XML output generated when serializing the Employee object at 2430 is shown in
The serial version number of each class is preferably stored as an attribute of the class elements, as shown at 2631 and 2641, so that it can be verified when the object is being deserialized. If the serial version number of a serialized object does not match the serial version number of the class identified in the object element, the underlying class definition of the object will be required to implement the SerializedObjectImporter interface. An implementation of this interface is an acknowledgement by the object that its definition has changed. For example, the class elements at 2630 and 2640 specify the names of classes used by the serialized object 2600. If the serial version numbers specified at 2631 or 2641 do not match the presently-existing serial version numbers for those classes when document 2600 is to be deserialized, then according to preferred embodiments, the Employee object 2620 cannot be deserialized unless either the Employee class 2300 or Person class 2200 implements the SerializedObjectImporter interface, respectively. For simplicity, the SerializedObjectImporter interface may always be initially implemented on the same class as the Serializable interface, then overridden and chained in each sub-class when necessary (as illustrated in
A special-object element is recognized by the deserializer as a serialized object that will be constructed during deserialization using a constructor or initializer methods. See elements 2632 and 2642, where special-object elements are used for serializing vectors. As mentioned earlier, special objects are used in preferred embodiments to avoid expanding the internal fields of commonly-used Java objects such as String, Vector, and ArrayList. This helps reduce the size of the XML output and hides the internal implementations of these Java objects. The special-object is also preferably used for Java objects that do not have zero-argument constructors. If the classes of the objects being serialized are known in advance, then in preferred embodiments, an implementation of the present invention need only handle applicable Java objects. (In this sample implementation, Java serialization extensions are not supported.)
The reference attribute in a serialized object such as that represented by document 2600, as stated earlier, helps maintain commonality between objects. In this example, the GUEST_ACCOUNT variable in the Person class is linked to an object in the accounts vector. See the code at 2230 in
The object stream classes depicted in
Turning now to
The custom import logic 2740 in this example includes code 2750 for changing the class name, and the statement at 2760 tests (preferably, using the serial version number or identifier, as has been described) to see if the class of the serialized object is different from the existing class definition for that object. In this example, migration of only one prior version of the object is supported. If migration of multiple prior versions is to be supported, then a version attribute is preferably added to the class, and the migration code then preferably checks this attribute when performing the migration. If the class definitions are different, then the migration logic comprising statements 2770-2795 is executed to migrate the previously-serialized object, as will now be described with reference to
The sample code 2800 in
Since the NewEmployee class 2700 implements the SerializedObjectImporter interface, the deserializer calls it when it is deserializing the NewEmployee object from the XML document 2600. The default importer successfully restores the contents of the Person object, which has not changed in this example, but it is the custom deserialization code (see reference numbers 2770-2795) that handles the new and changed fields of NewEmployee class (such as officeNumber, title, and so forth). Also, note that when calling XMLObjectInputStream.readObject( ) (see reference number 2810 of
In
Preferred embodiments of the present invention operate to transparently migrate serialized objects during normal product operation, thereby efficiently reflecting revised class definitions in the deserialized objects. Techniques which have been disclosed herein are easy to use and extendable, and may be employed for migrating arbitrary forms of objects even though extreme changes may have been made to classes used in those objects. To incorporate an implementation of the present invention into an existing code base, invocations of the Java serialization classes can simply be replaced with the XML object stream classes illustrated herein, thereby easily replacing Java serialization with XML serialization for all objects to be serialized. When using techniques disclosed herein, no dependency exists on having access to the original class definitions for performing deserialization.
Commonly-assigned and co-pending U.S. patent application Ser. No. 10/457,199 (filed Jun. 9, 2003), titled “Maintaining Multiple Valid Concurrent Serialized Object Versions”, discloses techniques for concurrently maintaining serialized objects that were created from more than one version of a class definition. According to preferred embodiments of this commonly-assigned invention, a component programmatically maps and enforces multiple valid versions of stream-unique version identifiers for a collection of class definitions (such as the classes of a software product that is undergoing change from one product version to another). This component programmatically detects when an object's stream-unique version identifier value does not match the code attempting to deserialize the object, and then programmatically determines whether the object is compatible with the code even though the stream-unique version identifier values do not match. Preferably, this determination is made by consulting a stored mapping, in which the stream-unique version identifiers of compatible versions have been recorded. This commonly assigned invention does not teach the techniques disclosed in the present invention.
While preferred embodiments have been described with reference to the Java programming language and features thereof, the teachings disclosed herein may be adapted for use with similar features of other programming languages, without deviating from the scope of the present invention.
As will be appreciated by one of skill in the art, embodiments of the present invention may be provided as methods, systems, or computer program products. Accordingly, the present invention may take the form of an entirely hardware embodiment, an entirely software embodiment, or an embodiment combining software and hardware aspects. Furthermore, the present invention may take the form of a computer program product which is embodied on one or more computer-usable storage media (including, but not limited to, disk storage, CD-ROM, optical storage, and so forth) having computer-usable program code embodied therein.
The present invention has been described with reference to block diagrams of methods, apparatus (systems), and computer program products according to embodiments of the invention. It will be understood that each block of the block diagrams, and combinations of blocks in the block diagrams, can be implemented by computer program instructions. These computer program instructions may be provided to a processor of a general purpose computer, special purpose computer, embedded processor, or other programmable data processing apparatus to produce a machine, such that the instructions, which execute via the processor of the computer or other programmable data processing apparatus, create means for implementing the functions specified in the block diagram block or blocks.
These computer program instructions may also be stored in a computer-readable memory that can direct a computer or other programmable data processing apparatus to function in a particular manner, such that the instructions stored in the computer-readable memory produce an article of manufacture including instruction means which implement the function specified in the block diagram block or blocks.
The computer program instructions may also be loaded onto a computer or other programmable data processing apparatus to cause a series of operational steps to be performed on the computer or other programmable apparatus to produce a computer implemented process such that the instructions which execute on the computer or other programmable apparatus provide steps for implementing the functions specified in the block diagram block or blocks.
While preferred embodiments of the present invention have been described, additional variations and modifications in those embodiments may occur to those skilled in the art once they learn of the basic inventive concepts. Therefore, it is intended that the appended claims shall be construed to include preferred embodiments and all such variations and modifications as fall within the spirit and scope of the invention.
Package util.xml.objectstream
Interface Summary
SerializedObjectImporter—An interface that imports a serialized object.
XMLSerializer—An interface that performs XML serialization and deserialization of arbitrary Java objects.
Class Summary
DefaultXMLSerializer—A class that performs XML serialization and deserialization of arbitrary Java objects.
SerializedObject—A class that represents a serialized object.
ArrayObject—A class that represents a serialized array object.
PrimitiveObject—A class that represents a serialized primitive object.
SpecialObject—A class that represents a serialized special object.
UserClass—A class that represents a serialized user class.
UserObject—A class that represents a serialized user object.
XMLObjectInputStream—A class that reads an XML input stream to deserialize an object from an XML element which represents the object.
XMLObjectOutputStream—A class that writes a serialized object to an XML output stream using an XML element which represents the object.
Exception Summary
XMLObjectStreamException—A class that represents XML object stream exceptions.
Package util.xml.stream
Class Summary
XMLInputStream—A class that reads an XML input stream to create an XML element which encapsulates the XML data.
XMLOutputStream—A class that writes an XML output stream using the encapsulated XML data stored in an XML element.
XMLElement—A class that represents an XML element.
Interface SerializedObjectImporter
Imports a serialized object into this object.
Interface XMLSerializer
This function performs the XML serialization by converting the object into an XML element.
This function performs the XML deserialization by converting the XML element into an object.
This function performs the XML deserialization by converting the XML element into the specified object.
Class DefaultXMLSerializer
Construct the default XML serializer and deserializer
Method Summary
This function performs the XML serialization by converting the object into an XML element.
This function performs the XML deserialization by converting the XML element into an object.
This function performs the XML deserialization by converting the XML element into the specified object.
This function is called before an object is deserialized to update class names that have been changed.
Class SerializedObject
A class that represents a serialized object. This class is also responsible for serializing and deserialiing objects into an XML stream.
Method Summary
Creates a serialized object that represents the XML element.
Performs the serialization by recursively creating the XML elements represented by the object.
Performs the deserialization by recursively creating and initializing the objects represented by the serialized object.
Performs the deserialization by recursively creating and initializing the objects represented by the serialized object.
Returns the class name.
Returns the name.
Returns the parent.
Returns the reference.
Returns the type.
Returns the value.
Indicates whether the object is null.
Replaces all occurrences of the old class name with the new class name.
Performs the serialization by recursively creating the XML elements represented by the object.
Performs the deserialization by recursively creating and initializing the objects represented by the serialized object.
Indicates whether the array contains sub-array elements.
Indicates whether the array contains primitive elements.
Returns the number of array entries.
Returns the specified array entry.
Returns the array length.
Returns the entire array list.
Performs the serialization by recursively creating the XML elements represented by the object.
Performs the deserialization by recursively creating and initializing the objects represented by the serialized object.
Performs the serialization by recursively creating the XML elements represented by the object.
Performs the deserialization by recursively creating and initializing the objects represented by the serialized object.
Returns the serialization method.
Returns the specified parameter entry.
Returns the number of parameter entries.
Returns the entire parameter list.
Class UserClass
Since user classes cannot be deserialized directly, an exception is thrown if this method is invoked.
Returns the specified field entry.
Returns the specified field entry.
Returns the number of field entries.
Returns the entire field list.
Returns the serial version of the class.
Indicates whether the class definition differs from the serialized definition.
Class UserObject
Performs the serialization by recursively creating the XML elements represented by the object.
Performs the deserialization by recursively creating and initializing the objects represented by the serialized object.
Performs the default import of the serialized object into the specified object.
Returns the specified class entry.
Returns the specified class entry.
Returns the specified class entry.
Returns the number of class entries.
Returns the entire class list.
Indicates whether the object is null.
Indicates whether the object definition differs from the serialized definition.
Class XMLObjectInputStream
Constructs an object for reading an XML input stream using the default XML serializer and deserializer.
Constructs an object for reading an XML input stream using a custom XML serializer and deserializer.
Method Summary
Closes the XML input stream.
Reads an object from the XML input stream.
Reads an object from the XML input stream and imports it into the specified object.
Class XMLObjectOutputStream
Constructs an object for writing an XML output stream using the default XML serializer and deserializer.
Constructs an object for writing an XML output stream using a custom XML serializer and deserializer.
Method Summary
Closes the XML output stream.
Flushes the XML output stream.
Writes an object to the XML output stream.
Class XMLObjectStreamException
A class that represents XML object stream exceptions.
Constructor Summary
Constructs an XML object stream exception.
Constructs an XML object stream exception.
Constructs an XML object stream exception.
Method Summary
Returns the embedded general exception.
Returns the exception error code.
Returns the exception message.
Returns the exception parameter.
Class XMLInputStream
Constructs an object for reading an XML input stream.
Method Summary
Closes the XML input stream.
XMLElement readXMLElement( )
Reads an XML element from the input stream, recursively traversing all child elements.
Class XMLOutStream
Constructs an object for writing an XML output stream.
Method Summary
Closes the XML output stream.
Flushes the XML output stream.
Writes an XML element to the output stream, recursively traversing all child elements.
Class XMLElement
Constructs an XML element.
Method Summary
Adds an attribute to the XML element.
Adds a child element to an XML element.
Returns the attribute value for the specified attribute name.
Returns the specified child element.
Returns the number of child elements.
Returns the entire child element list.
Returns the parent element.
Returns the XML tag body.
Returns the XML tag name.
Sets the XML tag body.
Sets the XML tag name.