United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6267224 : Migration, interoperation failures for serialized javax.xml.namespace.QName inst. betw EE 1.4,SE 5.0

Details
Type:
Bug
Submit Date:
2005-05-09
Status:
Resolved
Updated Date:
2017-05-16
Project Name:
JDK
Resolved Date:
2005-12-22
Component:
xml
OS:
solaris_7,windows_2003
Sub-Component:
jaxp
CPU:
other,x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
5.0u3,6
Fixed Versions:
5.0u7 (b01)

Related Reports
Duplicate:
Relates:
Relates:

Sub Tasks

Description
DESCRIPTION:
===========
Under jre5.0, an attempt to de-serialize an instance of the class javax.xml.namespace.QName, results in jvm throwing a java.io.InvalidClassException exception.

ROOT CAUSE:
==========
This issue is a result of the migration of javax.xml.namespace.QName
from J2EE1.4 to J2SE5.0; the exception is thrown as a result of a mismatch between the suid reported in the ojbect file ('qnameser.obj') and the suid hard-coded into QName.  Namely, in J2SE 5.0, the serialVersionUID of javax.xml.namespace.QName is declared:

    private static final long serialVersionUID = 4418622981026545151L;

but in J2EE 1.4 this value is different.

JDK VERSION INFORMATION: 
=======================
java version "1.5.0_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_03-b07)
Java HotSpot(TM) Server VM (build 1.5.0_03-b07, mixed mode)

INSTRUCTIONS TO RECREATE ISSUE:
==============================
The attached testcase and object file demonstrate the above issue.  Run the test case by typing the following at the command line:
$java QNameSerialTest d qnameser.obj 

NOTE: The file qnameser.obj was created using J2EE 1.4 and is available in the 'attachments' section.  

EXCEPTION DETAILS:
=================
When trying to run the test case (QNameSerialTest.java) - the following exception occurs:

Failure during deserialization.
java.io.InvalidClassException: javax.xml.namespace.QName; local class incompatible: stream classdesc serialVersionUID = -9120448754896609940, local class serialVersionUID = 4418622981026545151
        at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:519)
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1546)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1460)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1693)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1299)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:339)
        at QNameSerialTest.main(QNameSerialTest.java:37)


TESTCASE: 
========

import javax.xml.namespace.QName;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

//Tests object serialization and deserialization of javax.xml.namepace.QName. 

public class QNameSerialTest {
    public final static String TEST_QNAME = "{http://www.example.com}test";
    
    public static void main (String [] args) {
        if (args.length < 2) {
            printUsage();
            System.exit(1);
        }
        if ("s".equals(args[0])) {
            try { 
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(args[1]));
                QName qname = QName.valueOf(TEST_QNAME);
                oos.writeObject(qname);
                oos.flush();
                oos.close();
                System.out.println("QName has been serialized to file: " + args[1]);
            }
            catch (IOException exc) {
                System.err.println("Failure during serialization.");
                exc.printStackTrace();
            }
        }
        else if ("d".equals(args[0])) {
            try {
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream(args[1]));
                QName qname = (QName) ois.readObject();
                ois.close();
                System.out.println("Deserialization successful.");
                System.out.println("QName value: " + qname.toString());
            }
            catch (ClassNotFoundException exc) {
                System.err.println("Failure during deserialization.");
                exc.printStackTrace();
            }
            catch (IOException exc) {
                System.err.println("Failure during deserialization.");
                exc.printStackTrace();
            }
        }
        else {
            printUsage();
            System.exit(1);
        }
    }
    
    public static void printUsage() {
        System.err.println("Usage: java QNameSerialTest [s|d] file");
        System.err.println("s - serialize");
        System.err.println("d - deserialize");
    }
}
###@###.### 2005-05-09 13:40:48 GMT
###@###.### 2005-05-23 23:46:55 GMT
###@###.### 2005-05-24 00:33:42 GMT

                                    

Comments
EVALUATION

This CR belongs in whatever is the appropriate BT2 category for the javax.xml.namespace.QName class.  I'm making a best guess with jaxp/jaxp/other; please recategorize as appropriate.

Note that in J2SE 5.0, the serialVersionUID of javax.xml.namespace.QName is declared explicitly:

    private static final long serialVersionUID = 4418622981026545151L;

but to a value that is different from the value reported for J2EE 1.4.

###@###.### 2005-05-10 00:06:06 GMT

the serialVersionUID is correct per serialver tool.
this is being closed as not a bug.
###@###.### 2005-05-25 22:25:09 GMT
                                     
2005-05-10
WORK AROUND

There is no reasonable workaround since the JCK signature checks will force J2SE 5.0 to implement the new QName signatures (in which hashcode and equals methods are final, which changes the default serial version UID)
###@###.### 2005-05-09 13:40:48 GMT
                                     
2005-05-09



Hardware and Software, Engineered to Work Together