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: 4862448
Votes 0
Synopsis Unable to serialize anonymous classes.
Category java:serialization
Reported Against mantis-beta
Release Fixed
State 11-Closed, Not a Defect, request for enhancement
Priority: 3-Medium
Related Bugs
Submit Date 12-MAY-2003
Description




A DESCRIPTION OF THE REQUEST :
Java does not allow anonymous classes to be serialized.

This is due to the fact that the constructor generated by the compiler for an anonymous class is done so automatically, and a no-argument constructor is not constructed; furthermore, the compiler prevents the developer from defining their own no-argument contructor for the anonymous class.

Object serialization requires that a no-argument constructor be defined.


JUSTIFICATION :
There are many cases where it is desireable to have fields assigned objects using anonymous classes.

Correspondingly, it is oven desireable to serialize information (e.g., for network transport or for  customer ).

Preventing the developer from serializing all anyonmous classes is a severe restriction.



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The simplest solution is to automatically generate a no-argument constructor for all anonymous classes.
ACTUAL -
The current behavior prohibits the serialization of all anyonmous classes.
(Review ID: 185561) 
======================================================================
Work Around
See evaluation.
Evaluation
Object serialization only requires that a class defines a no-argument
constructor if it is externalizable.  If the class is serializable (but not
externalizable), then the class itself does not need to define a no-argument
constructor--its closest non-serializable superclass, however, must define a
subclass-accessible no-argument constructor.  For example, the following code
successfully serializes and deserializes an anonymous class instance; this is
possible because the anonymous class subclasses java.lang.Object, which defines
a public no-arg constructor:

  import java.io.*;
  
  public class Foo { 
      public static void main(String[] args) throws Exception {
          ByteArrayOutputStream bout = new ByteArrayOutputStream();
          ObjectOutputStream oout = new ObjectOutputStream(bout);
          oout.writeObject(new Serializable() {
              public String toString() { return "anonymous class instance"; }
          });
          oout.close();
          ObjectInputStream oin = new ObjectInputStream(
              new ByteArrayInputStream(bout.toByteArray()));
          System.out.println("deserialized: " + oin.readObject());
      } 
  }

Serialization of anonymous class instances, however, is discouraged due to
several known complications.  These are spelled out in section 1.10 of the
serialization specification:

  Note - Serialization of inner classes (i.e., nested classes that are not
  static member classes), including local and anonymous classes, is strongly
  discouraged for several reasons. Because inner classes declared in non-static
  contexts contain implicit non-transient references to enclosing class
  instances, serializing such an inner class instance will result in
  serialization of its associated outer class instance as well. Synthetic
  fields generated by javac (or other JavaTM compilers) to implement inner
  classes are implementation dependent and may vary between compilers;
  differences in such fields can disrupt compatibility as well as result in
  conflicting default serialVersionUID values. The names assigned to local and
  anonymous inner classes are also implementation dependent and may differ
  between compilers. Since inner classes cannot declare static members other
  than compile-time constant fields, they cannot use the serialPersistentFields
  mechanism to designate serializable fields. Finally, because inner classes
  associated with outer instances do not have zero-argument constructors
  (constructors of such inner classes implicitly accept the enclosing instance
  as a prepended parameter), they cannot implement Externalizable. None of the
  issues listed above, however, apply to static member classes.

Foremost among these issues is the fact that anonymous classes do not have
well-defined names--it's up to the compiler to choose a name for the class.
This means that if you take an application that serializes an anonymous class,
and happen to compile the writing and reading ends of it with different
versions/implementations of javac, then serialization of the class may very
well fail, since there's no agreed name for the class (i.e., if the sender
uses the class name Foo$1 and the receiver uses Foo$2, serialization has no way
of knowing that Foo$1 should map to Foo$2).  An easy workaround for this issue
is to use a named class instead of an anonymous class.  In light of the issues
enumerated above, it's also recommended that this named class be either a
non-nested class, or, if it must be nested, a static member class.

  xxxxx@xxxxx   2003-05-15
Comments
  
  Include a link with my name & email   

Submitted On 12-FEB-2009
Anonymous object of an anonymous class can be serialized iff parent interface or class implements seriazable. if its not,it will throw java.io.NotSerializableException as there is no way of implementing a serializable interface through anonymous class implementation



import java.io.*;
public class Foo {
      public static void main(String[] args) throws Exception {
          ByteArrayOutputStream bout = new ByteArrayOutputStream();
          ObjectOutputStream oout = new ObjectOutputStream(bout);
          oout.writeObject(new TestInterface() {
            public String toString() { return "TestInterface class instance"; }

            public void print() {
                System.out.println("My Name is TestInterface");
            }
          });
          oout.close();
          ObjectInputStream oin = new ObjectInputStream(
              new ByteArrayInputStream(bout.toByteArray()));
          System.out.println("deserialized: " + oin.readObject());
          
      }
  }


public interface TestInterface extends Serializable {

    public void print();


}


Thanks
Jit Sen

mail.jitsen@gmail.com


Submitted On 12-FEB-2009
As per posted by Jit I agree. Only adding to his comments objects that are transferred over network are also elligible for Serializable. Hence in web projects also you can face this issue while writing a customized class. We faced this issue while using the apache trinidad <tr:validateDateRestriction>  tag and it's attribute inValidDays. This required to implement  org.apache.myfaces.trinidad.model.DateListProvider which does not implement the java.io.Serializable interface!

Anirban Datta
adcal15@yahoo.com



PLEASE NOTE: JDK6 is formerly known as Project Mustang