JDK-4634165 : REGRESSION: Exceptions serialized in 1.4beta3 unserializable by jdk 1.1.x
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io:serialization
  • Affected Version: 1.4.0
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2002-02-06
  • Updated: 2002-02-07
  • Resolved: 2002-02-07
Related Reports
Relates :  
Description

Name: gm110360			Date: 02/06/2002


FULL PRODUCT VERSION :
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta3-b84)
Java HotSpot(TM) Client VM (build 1.4.0-beta3-b84, mixed mode)

FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]



A DESCRIPTION OF THE PROBLEM :
Exceptions and subclasses (and possibly Throwable
subclasses - haven't tested) serialized in 1.4 (Tomcat 3.2
server) can not be deserialized using jdk 1.1 (Internet
Explorer client).


REGRESSION.  Last worked in version 1.3.1

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Write a servlet that serializes an Exception (or
subclass) to the response outputstream.
2. Write an applet that reads the object.
3. Run the servlet and serve the applet on Tomcat 3.2 (will
probably work on any server running in 1.4 though)
4. Connect to the servlet using the applet in a 1.1 client
(i.e. Internet Explorer)

EXPECTED VERSUS ACTUAL BEHAVIOR :
Surely Exceptions should be serializable between different
VMs, as they were before 1.4?

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.ClassNotFoundException
	at java/io/ObjectInputStream.loadClass0 (ObjectInputStream.java)
	at java/io/ObjectInputStream.resolveClass (ObjectInputStream.java:852)
	at java/io/ObjectInputStream.readClassDescriptor
(ObjectInputStream.java:1165)
	at java/io/ObjectInputStream.readArray (ObjectInputStream.java:1100)
	at java/io/ObjectInputStream.checkSpecialCases
(ObjectInputStream.java:1063)
	at java/io/ObjectInputStream.readObject (ObjectInputStream.java:300)
	at java/io/ObjectStreamClass.doMismatchedRead (ObjectStreamClass.java)
	at java/io/ObjectInputStream.defaultReadObject
(ObjectInputStream.java:448)
	at java/io/ObjectInputStream.readNewObject (ObjectInputStream.java:1296)
	at java/io/ObjectInputStream.readObject (ObjectInputStream.java:309)

This bug can be reproduced always.

---------- BEGIN SOURCE ----------
A test applet:

import java.io.*;
import java.net.*;
public class TestApplet extends java.applet.Applet {

    public void init () {
        try
        {
            URL url = new URL(getCodeBase()+"servlet/TestServlet");
            URLConnection urlConn = url.openConnection();
            ObjectInputStream ois =
                new ObjectInputStream(urlConn.getInputStream());
            Object obj = ois.readObject();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

and a test servlet:

import javax.servlet.*;
import javax.servlet.http.*;
public class TestServlet extends HttpServlet {

    protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
    throws ServletException, java.io.IOException {
        java.io.ObjectOutputStream out =
            new java.io.ObjectOutputStream(response.getOutputStream());
        out.writeObject(new Exception("Test Exception"));
        out.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse
response)
    throws ServletException, java.io.IOException {
        processRequest(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse
response)
    throws ServletException, java.io.IOException {
        processRequest(request, response);
    }
}

---------- END SOURCE ----------

Release Regression From : merlin-beta3
The above release value was the last known release where this 
bug was known to work. Since then there has been a regression.

Release Regression From : merlin-beta3
The above release value was the last known release where this 
bug was known to work. Since then there has been a regression.

(Review ID: 138558) 
======================================================================

Comments
WORK AROUND See evaluation.
11-06-2004

PUBLIC COMMENTS Instances of java.lang.Throwable and subclasses (i.e., any exceptions) serialized by JDK 1.4 cannot be deserialized by the (Microsoft) JDK 1.1 implementation that Internet Explorer uses. Deserialization results in a ClassNotFoundException being thrown.
10-06-2004

EVALUATION The root cause of this problem is that the JVM in Internet Explorer exhibits bug 4088176 ("backward compat. fails reading an evolved class with new field, nonexistant class"), which was fixed in (Sun's) JDK 1.1.6. Presumably the implementation of serialization in Internet Explorer's JVM was based off of JDK code prior to 1.1.6, or was independently implemented with the bug (note: from the stack trace given, the ObjectInputStream implementation in Internet Explorer's JVM does not appear to closely match any of Sun's implementations from 1.1 through 1.1.5). The reason that J2SE 1.4 triggers this problem is as follows: in J2SE 1.4, a new serializable field "stackTrace" of type java.lang.StackTraceElement[] was added to java.lang.Throwable. The StackTraceElement class is itself new to 1.4, and is not present in JDK 1.1.x. Because of bug 4088176, this causes deserialization to fail in JDK <= 1.1.5 (including Internet Explorer's JVM). The correct behavior (as documented by 4088176) is for the receiving VM to disregard the failure to resolve StackTraceElement, since the field it is associated with is not present in the local (1.1.x) version of java.lang.Throwable. Note that deserialization of exceptions written by 1.4 works properly in JDK 1.1.6 and later. Since this failure is caused by a bug in the deserializing (applet-side) JVM, and we do not have any means of affecting the serialization code in the JVM bundled with Internet Explorer, there is no way to fix the underlying bug directly, given the deployment described. Several workarounds are possible, however: 1. Use JDK 1.3.x or earlier for the server end. Since the added "stackTrace" field is absent from JDK <= 1.3.x, this would avoid the particular failure described. However, any other serializable classes with added fields whose types are unresolvable in Internet Explorer's JVM will trigger similar deserialization failures. 2. Use the Java Plug-In or Java WebStart on the client side. Both employ JVMs in which 4088176 is fixed. Closing as "will not fix", since the addition of StackTraceElement to Throwable's serial form in 1.4 is completely legal, and the root cause of the failure is due to 4088176 in code that is beyond our control. ###@###.### 2002-02-07
07-02-2002