EVALUATION
Here is an evaluation by Ken Cavanaugh.
I haven't looked at this part of the code in probably 10 years. Taking a quick look this morning, I think the customer is correct. The idlj-generated serialization code is extremely bad, both because it does not destroy the ORB it creates, and it does not do anything to cache the ORB (creating an ORB can be quite expensive). In fact, I agree with the customer that no ORB should be created for this.
However, we do have a problem: it appears that there is no standard, portable serialization format or mechanism defined for IDL generated stubs. Literally all the the spec says is the following (taken from http://www.omg.org/spec/I2JAV/1.3/PDF section 4.4.1.3):
Those generated classes that are not abstract, including the stub classes, shall support Java object serialization semantics.
For example, generated helper classes do not have to be serializable. The following classes support Java object
serialization semantics:
* Stub classes
* Abstract base classes for concrete valuetypes
* Implementation classes for concrete valuetypes
* Any class that implements IDLEntity
That specification is not implementable in any reasonable fashion that is standard and portable.
The reverse mapping (Java to IDL, with stubs generated by rmic -iiop) DOES carefully define a serialization format for stubs, and it can be implemented portably without needing to create an ORB. The serialization format is defined in the OMG specification http://www.omg.org/spec/JAV2I/1.4/PDF in section 4.5.1.2 as follows:
The writeObject and readObject methods support stub serialization and deserialization by saving and restoring the
IOR associated with the stub. The writeObject method writes the following data to the serialization stream:
1. int - length of IOR type id
2. byte[] - IOR type ID encoded using ISO 8859-1 (written using a write call, not a writeObject call)
3. int - number of IOR profiles
4. For each IOR profile:
1. int - profile tag
2. int - length of profile data
3. byte[] - profile data (written using a write call, not a writeObject call).
We should probably look at doing something similar in the IDL case. However, this is NOT compatible with the format used today in the current IDLJ-generated stubs, and creating a library to do the current string_to_object/object_to_string equivalent would create some other problems. Any solution here is going to lack both portability (because we cannot add new classes to the org.omg.* package, therefore no one else's ORB can assume that it can access any new code) and interoperability (because there is no real standard for IDL stub serialization). The current implementation of string_to_object and object_to_string uses a lot of ORB machinery (notably the CDR streams) to implement the functionality of converting to a string.
One simple thing that could be done here is to fix the current bad code, e.g. replace
private void readObject (java.io.ObjectInputStream s) throws java.io.IOException
{
String str = s.readUTF ();
String[] args = null;
java.util.Properties props = null;
org.omg.CORBA.Object obj = org.omg.CORBA.ORB.init (args, props).string_to_object (str);
org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl) obj)._get_delegate ();
_set_delegate (delegate);
}
with
private void readObject( java.io.ObjectInputStream s ) throws java.io.IOException {
String str = s.readUTF() ;
String[] args = null ;
java.util.Properties = null ;
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init( args, props ) ;
try {
org.omg.CORBA.Object obj = orb.string_to_object( str ) ;
org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate() ;
_set_delegate( delegate ) ;
} finally {
orb.destroy() ;
}
}
and similarly for writeObject. This simply fixes the worst of the problems with the current code, but the customer may still have performance issues if they do this sort of operation frequently. Caching is possible, with a static data member in the stub that has a weak reference to an ORB, so that the ORB can be GCed when needed (weak references did not exist in Java when this part of idlj was written). Sustaining should be able to handle this sort of change, if the customer has a support contract so that they can open an escalation.
|