Previous | Table of Contents | Next |
The OMG IDL format defined above does not include any structural information. Identity of IDL types determined for this format
depends upon the names used in the RepositoryID being correct. For interfaces, if stubs and skeletons are not actually in
synch, even though the RepositoryIds report they are, the worst that can happen is that the result of an invocation is a BAD_OPERATION
exception. With value types, these kinds of errors are more problematic. An inconsistency between the stub and skeleton marshaling/unmarshaling
code can confuse the marshaling engine and may even corrupt memory and/or cause a crash failure.
The RMI Hashed format is used for Java RMI values mapped to IDL using the Java to IDL Mapping (see the Java/IDL Language Mapping
document). It is computed based upon the structural information of the original Java definition. Whenever the Java definition
changes, the hash function will (statistically) produce a hash code, which is different from the previous one. When an ORB
run time receives a value with a different hash from what is expected, it is free to raise a BAD_PARAM exception. It may also
try to resolve the incompatibility by some means. If it is not successful, then it shall raise the BAD_PARAM exception.
An RMI Hashed RepositoryId consists of either three or four components, separated by colons:
RMI: <class name> : <hash code> [ : <serialization version UID> ]
The class name is a Java class name as returned by the getName method of java.lang.Class. Any characters not in ISO Latin
1 are replaced by “\U? followed by the 4 hexadecimal characters (in upper case) representing the Unicode value.
For classes that do not implement java.io.Serializable, and for interfaces, the hash code is always zero, and the RepositoryID
does not contain a serial version UID.
For classes that implement java.io.Externalizable, the hash code is always the 64-bit value 1.
For classes that implement java.io.Serializable but not java.io.Externalizable, the hash code is a 64-bit hash of a stream
of bytes. (transcribed as a 16-digit upper case hex string). An instance of java.lang.DataOutputStream is used to convert
primitive data types to a sequence of bytes. The sequence of items in the stream is as follows:
1. The hash code of the superclass, written as a 64-bit long.
2. The value 1 if the class has no writeObject method, or the value 2 if the class has a writeObject method, written as a 32-bit integer.
3. For each field of the class that is mapped to IDL, sorted lexicographically by Java field name, in increasing order:
a. Java field name, in UTF encoding
b. field descriptor, as defined by the Java Virtual Machine Specification, in UTF encoding
The National Institute of Standards and Technology (NIST) Secure Hash Algorithm (SHA-1) is executed on the stream of bytes
produced by DataOutputStream, producing a 20 byte array of values, sha[0..19]. The hash code is assembled from the first 8
bytes of this array as follows:
long hash = 0;for (int i = 0; i < Math.min(8, sha.length); i++) {hash += (long)(sha[i] & 255) << (i * 8); }
For Serializable (including Externalizable) classes, the Java serialization version UID, transcribed as a 16 digit upper-case
hex string, shall be appended to the RepositoryId following the hash code and a colon. The Java serialization version UID
is defined in the Java Object Serialization Specification.
Examples for the valuetype ::foo::bar would be
RMI:foo/bar;:1234567812345678
RMI:foo/bar;:1234567812345678:ABCD123456781234
An example of a Java array of valuetype ::foo::bar would be
RMI:[Lfoo.bar;:1234567812345678:ABCD123456781234
For a Java class x\u03bCy that contains a Unicode character not in ISO Latin 1, an example RepositoryId is
RMI:foo.x\U03BCy:8765432187654321
A conforming implementation that uses this format shall implement the standard hash algorithm defined above.