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: 4171142
Votes 95
Synopsis Deserialization fails for Class object of primitive type
Category java:serialization
Reported Against 1.2 , 1.3 , 1.1.3 , 1.2.1 , 1.2.2 , 1.2fcs , kestrel-beta
Release Fixed 1.4(merlin-beta)
State 10-Fix Delivered, Verified, bug
Priority: 5-Very Low
Related Bugs 4264920 , 4339184 , 4442373 , 4519050 , 4662491
Submit Date 03-SEP-1998
Description




package jp.go.etl.takagi.test.bug_deserializing_class_of_primitive_type;
import java.io.*;
public class Test {
    public static void main(String[] args) throws Exception {
        PipedOutputStream os = new PipedOutputStream();
        InputStream is = new PipedInputStream(os);
        ObjectOutput oo = new ObjectOutputStream(os);
        ObjectInput oi = new ObjectInputStream(is);
        oo.writeObject(Integer.class);
        System.out.println(oi.readObject());
        oo.writeObject(int.class);
        System.out.println(oi.readObject());
    }
}
 
> java jp.go.etl.takagi.test.bug_deserializing_class_of_primitive_type.Test
class java.lang.Integer
java.lang.ClassNotFoundException: int
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:352)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:233)
        at jp.go.etl.takagi.test.bug_deserializing_class_of_primitive_type.Test.main(Test.java:12)
(Review ID: 34926)
======================================================================




Consider the following example:

import java.io.*;
import java.util.*;

public class Serial implements Serializable {
    Class cl = int.class;

    public static void main(String[] args){
        try {
            FileOutputStream out = new FileOutputStream("tmp");
            ObjectOutputStream ous = new ObjectOutputStream(out);
            ous.writeObject(new Serial());
            ous.close();

            FileInputStream in = new FileInputStream("tmp");
            ObjectInputStream ins = new ObjectInputStream(in);
            Serial s = (Serial)ins.readObject();
            ins.close();
        } catch (Throwable e) {
            System.out.println(e);
        }
    }

}

when run, it produces the following results:

J:\borsotti\jtest>java Serial
java.lang.ClassNotFoundException: int

The same problem occurs if the value of the serializable
field is another primitive class, like e.g. double, void, etc.
(Review ID: 95240)
======================================================================
Work Around
The following override of ObjectInputStream.resolveClass() works around the
problem encounted. The problem is that ObjectStreamClass.resolveClass()
does not work for ObjectStreamClass descriptors for primitive types, such as
int or long.

class MyObjectInputStream extends ObjectInputStream {
    public MyObjectInputStream(InputStream is) 
	throws IOException, StreamCorruptedException
    {
	super(is);
    }
    
    public Class resolveClass(ObjectStreamClass desc) 
	throws ClassNotFoundException, IOException
    {
	try { 
	    return super.resolveClass(desc);
	} catch (ClassNotFoundException e) {
            if (desc.getName().equals("int"))
	        return int.class;
	    else /* check for other primitive types if one wishes.*/
	        throw e;
        }
    }
}
Evaluation
See public summary.
Comments
  
  Include a link with my name & email   

Submitted On 18-SEP-1998
malf
This doesn't work in jdk 1.1.6 either, it throws
an "java.io.NotSerializableException: int" exception
when writing a primitive class object. The problem
seems to be lack of support for primitive types in
java.io.ObjectStreamClass.java.


Submitted On 11-MAR-1999
kriff
The problem would be fixed if Class.forName
recognized "int" (and the other primitive types)
as a special case and returned the proper Class
object. The javadocs for Class.forName explicitly
state that this won't work because the classloader
will look for a class named "int" in the default
package. This makes no sense because its impossible
to declare a class named "int" ("int" is a keyword).


Submitted On 21-OCT-1999
dtropp
3 people from my team just spent 2 days trying to track down this bug in our
client/server
application (using RMI, ie. serialization).
This needs to be fixed!!!
The constraint (which I believe relates to security in some way) should be
changed.


Submitted On 22-NOV-1999
davey
I just spent over a day rediscovering this.


Submitted On 02-FEB-2000
jeff_nielsen
I also just wasted hours re-discovering this.  I'm not quite sure how to use
the 
workaround provided above in the context of RMI.  How do I get 
sun.rmi.server.UnicastRef.unmarshalValue() to use an instance of
MyObjectInputStream
rather than the default ObjectInputStream???


Submitted On 28-FEB-2000
burner
I have also wasted a day rediscovering this bug. Quite 
annoying. How hard would it be to fix?


Submitted On 09-MAR-2000
oliverrode
The community is waiting 18 month now.
When will Sun fix this serious bug ?!


Submitted On 12-APR-2000
pangh
I wasted couple of hours to re-discover this bug. I think 
it should be easy to fix and I cannot see any security 
issue related to it.


Submitted On 28-APR-2000
Pipi
Please Sun, fix this Bug !!


Submitted On 17-MAY-2000
joco
Why is this bug still in 1.3????
Please sun just use the above workaround for the 
ObjectInputStream or rewrite the Default ClassLoader so 
that it also returns classes of primitives (best solution)


Submitted On 16-JUN-2000
babiak
Fri Jun 16 14:22:59 GMT+02:00 2000

Milan Babiak <Milan.Babiak@icl.sk>

I have found this bug in JDK 1.2.2, but in Oracle 
JDeveloper Version 2.0 (Build 343) it works correctly. 

Java version is:

C:\Testing>"C:\Program Files\Oracle\JDeveloper 2.0\java1.2
\jre\bin\java.exe" -version
java version "internal_build"
Ferrari (Copyright (c) 1998, 1999  Oracle Corp.  Version 
1.2.078 odv, nojit)


Submitted On 05-SEP-2000
adepue
We spent hours tracking this one down while working on our 
RMI based remote management system.  We went down rabbit 
trails thinking it was the ClassLoader of the IDE our 
management console resides in.  We are going to figure out 
a work around, of course, but it isn't obvious at first 
what the workaround is for RMI.  This is a simple thing 
that is very annoying and difficult.  Why not just let 
Class.forName detect "int", "long", and all the others?  
You can't make classes with those names anyway!


Submitted On 12-NOV-2000
pmurray
Dammit! Maybe this is what was the problem on my project! I 
was writing a generic proxy, where you pass it a CORBA 
handle, a java.lang.reflect.Method, and an argument list. 
Could *not* get it to work, eventually just passed 
everything as Strings. Thanks, BugParade, for pointing out 
a solution. But I'd prefer the bug fix to be at your end.


Submitted On 06-DEC-2000
ssoltysik
2 Years seems like a long time for this bug to go un-fixed. 


Submitted On 10-MAY-2001
mbecke
This bug says that it has been fixed, but it still doesn't work for me.  I've tried this in the most recent versions of the JDK for Linux and Windows.  What's the deal?


Submitted On 12-MAY-2001
bestsss
mbecke, merlin is not available though it is one of the most expected version 
'cause of Non-block IO...
U have to hold ur horses


Submitted On 23-MAY-2001
fablumos
Still not fixed for me as well !


Submitted On 30-MAY-2001
larsona
ARRGH - Sun fix this damn bug! (And all the other cludges 
for primitives in reflection)


Submitted On 10-NOV-2001
thomas.mahler
This is really an annoying bug I wasted 3 days on debugging
!!!
Why is this bug marked as closed and fixed when it is still
present in JDK 1.3 ?


Submitted On 03-DEC-2001
Gauravc
Why not change the java.io.ObjectStreamClass.class so that 
when the class descriptor is read, the jdk knows that it is 
a class object representing the primitive type and not call 
resolveObject. Instead call 
java.lang.Class.getPrimitiveClass.


Submitted On 11-APR-2002
meherzad77
So how does this workaround work if I have int[], int[][], 
int[][][] - am I supposed to have one case for each of 
these? 



PLEASE NOTE: JDK6 is formerly known as Project Mustang