-
Bug
-
Resolution: Fixed
-
P4
-
1.2.2
-
beta
-
generic, x86
-
generic, windows_nt
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2035176 | 1.4.2 | Anita Jindal | P4 | Closed | Fixed | only |
Name: md23716 Date: 07/04/2000
RMI RepositoryIDs take the form RMI:<class name>:<hash code>:<suid>. There are errors in the calculation of both the <hash code> part and the <suid> part. A testcase called ShowRepid has been included that can be used to display calculated repids or run a check on several known problem classes.
1. The repid for the Java class "java.lang.Class" is wrong.
The <hash code> piece is missing and the <suid> appears using lower-case characters, they should be in upper-case.
Run "java ShowRepid java.lang.Class" to test.
2. <suid> is incorrect if there is a "static final long serialVersionUID" field that is *not* declared "private".
It should not matter whether this field is private or public. The java.lang.GregorianCalendar has a non-private serialVersionUID field, for example.
Run "java ShowRepid java.util.GregorianCalendar" to test.
Or run "java ShowRepid ShowRepid" to test.
3. A "writeObject()" method can be ignored when calculating <hash code>.
In com.sun.corba.se.internal.io.ObjectStreamClass.java in the method computeStructuralUID() (at lines 1008 to 1011) there is a check for osc.hasWriteObject() before writing a 1 or a 2 to the output stream. However due to the order of execution of the code in ObjectStreamClass constructor the boolean flag being tested does not (always) get set until *after* this test has been made. This effectively ends up ignoring the fact that there is a writeObject() method in a class and always writes a 1 to the output stream.
Run "java ShowRepid ShowRepid" to test.
4. When calculating the <hash code> the parent class is ignored if it is java.lang.Object.
There is nothing in the CORBA spec to suggest this should happen.
com.sun.corba.se.internal.io.ObjectStreamClass.java in method computeStructuralUID() (at line 1003) contains the offending code.
Run "java ShowRepid ShowRepid" to test.
5. Use of a "serialPersistentFields" array is ignored in calculating <hash code>.
In the CORBA v2.3 spec section 10.6.2 it describes how to calculate the <hash code> for a java.io.Serializable:
"1. The hash code of the superclass ...
2. The value 1 if no writeObject ....
3. For each field of the class that is mapped to IDL ...."
The key phrase here is "that is mapped to IDL". This process is described in "Java to IDL mapping" section 1.3.5.6 and it has to take account of any "serialPersistentFields" array. The current logic in com.sun.corba.se.internal.io.ObjectStreamClass.computeStructuralUID() (lines 1013 to 1029) simply takes all declared fields and ignores "transitent"s and "static"s.
This is harder to test and its hard to create a testcase for this one item given all the other things that are wrong with <hash code>. However it looks like java.io.ObjectStreamClass might be a good test.
Run "java ShowRepid java.io.ObjectStreamClass" to test.
6. Final <hash code> calculation is incorrect.
Again in ObjectStreamClass.computeStructuralUID() (at lines 1036 to 1039), the logic ends up using bytes
8 to 1 from the hasharray[] to calculate the hash code. It should be using bytes 0 to 7 (CORBA v2.3 spec, section 10.6.2).
Run "java ShowRepid ShowRepid" to test.
--- Test Case Start ---
*
* This will print the CORBA RepositoryId for a specified Java class.
*
* If the rules laid down in the CORBA spec (section 10.6.2) and the
* CORBA Java-to-IDL spec (section 1.3.5.6) are followed, I believe
* the following results should be obtained:
*
*
* java ShowRepid java.lang.Class
* class java.lang.Class = RMI:javax.rmi.CORBA.ClassDesc:2BABDA04587ADCCC:CFBF02CF5294176B
*
* java ShowRepid java.util.GregorianCalendar
* class java.util.GregorianCalendar = RMI:java.util.GregorianCalendar:450042FBA7A923B1:8F3DD7D6E5B0D0C1
*
* java ShowRepid java.io.ObjectStreamClass
* class java.io.ObjectStreamClass = RMI:java.io.ObjectStreamClass:071DA8BE7F971128:AB0E6F1AEEFE7B88
*
* java ShowRepid ShowRepid
* class ShowRepid = RMI:ShowRepid:AC117E28FE36587A:0000000000001234
*/
import java.io.*;
import com.sun.corba.se.internal.util.RepositoryId;
public class ShowRepid implements Serializable {
static final long serialVersionUID = 0x1234;
private void writeObject(ObjectOutputStream s) throws IOException {
}
private static int runTest() {
int rc = 0;
String r1 = "RMI:javax.rmi.CORBA.ClassDesc:2BABDA04587ADCCC:CFBF02CF5294176B";
String r2 = "RMI:java.util.GregorianCalendar:450042FBA7A923B1:8F3DD7D6E5B0D0C1";
String r3 = "RMI:java.io.ObjectStreamClass:071DA8BE7F971128:AB0E6F1AEEFE7B88";
String r4 = "RMI:ShowRepid:AC117E28FE36587A:0000000000001234";
String s1 = RepositoryId.createForAnyType(java.lang.Class.class);
String s2 = RepositoryId.createForAnyType(java.util.GregorianCalendar.class);
String s3 = RepositoryId.createForAnyType(java.io.ObjectStreamClass.class);
String s4 = RepositoryId.createForAnyType(ShowRepid.class);
if (!s1.equals(r1)) ++rc;
if (!s2.equals(r2)) ++rc;
if (!s3.equals(r3)) ++rc;
if (!s4.equals(r4)) ++rc;
return rc;
}
public static void main(String[] args) {
if (args.length == 0) {
if (runTest() == 0)
System.out.println("Test PASSED");
else
System.out.println("Test FAILED");
} else {
try {
Class clz = Class.forName(args[0]);
System.out.print(clz + " = ");
System.out.println(RepositoryId.createForAnyType(clz));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
--- Test Case End ---
======================================================================
- backported by
-
JDK-2035176 Incorrect CORBA RepositoryID calculations
-
- Closed
-
- duplicates
-
JDK-4369024 Interoperability problem with incorrect RepositoryIds
-
- Closed
-
- relates to
-
JDK-4365188 Bugs in RMI-IIOP Serialization protocol prevents Object Evolution
-
- Resolved
-