Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4350294
Votes 0
Synopsis Incorrect CORBA RepositoryID calculations
Category idl:java-idl
Reported Against 1.2.2
Release Fixed merlin-beta, master-only(Bug ID:2035176)
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs 4365188 , 4369024
Submit Date 04-JUL-2000
Description



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  customer  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  customer  = RepositoryId.createForAnyType(java.io.ObjectStreamClass.class);
	String s4 = RepositoryId.createForAnyType(ShowRepid.class);

	if (!s1.equals(r1)) ++rc;
	if (!s2.equals(r2)) ++rc;
	if (! customer .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 ---


======================================================================
Work Around
N/A
Evaluation
We are trying to incorporate fixes for Repository Id calculations.  Spec is 
unclear in some areas, e.g., in cases where it describes using fields for
computing rep-id hash.  I incorporated all fixes, but am still seeing mismatches in  some areas.  I am trying to use the example that was provided as part of this bug  to test the changes.  Please let me know if you are aware of any spec issues in this area or any bugs in the example code that was provided as part of the bug.  

The testcase has the following:
===============================

 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";
        
I added r5 to the example from the spec.
 
 String r5 = "RMI:java.util.Hashtable:C03324C0EA357270:13BB0F25214AE4B8";


The result I am getting is the following:

  Calculated Rep-Ids (after modifications)  
  ==================  
RMI:javax.rmi.CORBA.ClassDesc:2BABDA04587ADCCC:CFBF02CF5294176B
RMI:java.util.GregorianCalendar:450042FBA7A923B1:8F3DD7D6E5B0D0C1
RMI:java.io.ObjectStreamClass:C7E57DC7CAACEB5E:AB0E6F1AEEFE7B88
RMI:ShowRepid:AC117E28FE36587A:0000000000001234
RMI:java.util.Hashtable:86573568A211C011:13BB0F25214AE4B8
  ==================  
  Calculated Against Provided 
  ==================  
mismatch RMI:java.io.ObjectStreamClass:C7E57DC7CAACEB5E:AB0E6F1AEEFE7B88
mismatch RMI:java.util.Hashtable:86573568A211C011:13BB0F25214AE4B8
Test FAILED

I would appreciate your response on this.

- Thanks
Anita

  xxxxx@xxxxx   2000-08-02

There was a bug in the internal.io.ObjectStreamClass, which was not initializing hasPersistentFields even though it was defined. 


  xxxxx@xxxxx   2000-08-15
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang