United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-5015403 : LTP: XMLEncoder does not encode enumerations correctly

Details
Type:
Bug
Submit Date:
2004-03-18
Status:
Resolved
Updated Date:
2006-05-10
Project Name:
JDK
Resolved Date:
2006-05-10
Component:
client-libs
OS:
linux,windows_xp
Sub-Component:
java.beans
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
5.0,6
Fixed Versions:

Related Reports
Duplicate:
Relates:
Relates:

Sub Tasks

Description
Name: rmT116609			Date: 03/17/2004


FULL PRODUCT VERSION :

[cheiny@venom encoderbug]$ java -version
java version "1.5.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b32c)
Java HotSpot(TM) Client VM (build 1.5.0-beta-b32c, mixed mode)
[cheiny@venom encoderbug]$

ADDITIONAL OS VERSION INFORMATION :

[cheiny@venom encoderbug]$ uname -a
Linux venom 2.4.20-8 #1 Thu Mar 13 17:18:24 EST 2003 i686 athlon i386 GNU/Linux
[cheiny@venom encoderbug]$

A DESCRIPTION OF THE PROBLEM :
XMLEncoder is not serializing an enumeration correctly.  Instead it is allowing the field/property to default.  This is not good - the serialized information cannot be read back.  Result data is lost.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Save the source code in the attached examples as BugBean.java and BugMain.java

2) compile with "javac -source 1.5 BugBean.java BugMain.java"

3) run with "java -cp . BugMain"

4) Look in the file "bb.out" to see the serialized bean.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
5 - expected) property plaf should be equal to Metal (or something like that)
ACTUAL -
5 - actual) the plaf property is defaulted.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/*
 * BugBean.java
 *
 * Created on March 17, 2004, 12:24 PM
 */

import java.beans.*;
import java.io.Serializable;

/**
 * @author cheiny
 */
public class BugBean extends Object implements Serializable {
    
    public enum Plaf  {metal, windows, gtk, unknown}
    
    private PropertyChangeSupport propertySupport;
    
    /**
     * Holds value of property plaf.
     */
    private Plaf plaf = Plaf.unknown;
    
    public BugBean() {
        propertySupport = new PropertyChangeSupport(this);
    }
    
    
    public void addPropertyChangeListener(PropertyChangeListener listener) {
        propertySupport.addPropertyChangeListener(listener);
    }
    
    public void removePropertyChangeListener(PropertyChangeListener listener) {
        propertySupport.removePropertyChangeListener(listener);
    }
    
    /**
     * Getter for property plaf.
     * @return Value of property plaf.
     */
    public Plaf getPlaf() {
        return this.plaf;
    }
    
    /**
     * Setter for property plaf.
     * @param plaf New value of property plaf.
     */
    public void setPlaf(Plaf plaf) {
        Plaf oldPlaf = this.plaf;
        this.plaf = plaf;
        propertySupport.firePropertyChange("plaf", oldPlaf, plaf);
    }
    
}




/*
 * BugMain.java
 *
 * Created on March 17, 2004, 12:29 PM
 */

import java.io.*;
import java.beans.*;

/**
 *
 * @author  cheiny
 */
public class BugMain {
    
    /** Creates a new instance of BugMain */
    public BugMain() {
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        BugBean bb = new BugBean();
    
        File f = new java.io.File("bb.out");
        
        bb.setPlaf(BugBean.Plaf.metal);
        try {
            XMLEncoder e = new XMLEncoder(
                new BufferedOutputStream(
                    new FileOutputStream(f)));
            System.out.println("Saving to " + f.getAbsoluteFile() + ".  Plaf = " + bb.getPlaf());
            e.writeObject(bb);
            e.flush();
            e.close();
        System.out.println("    done, plaf = " + bb.getPlaf());
        } catch ( Exception x ) {
            System.err.println("Failed to save preferences: " + x.getMessage());
        }
    }
    
}

---------- END SOURCE ----------
(Incident Review ID: 243958) 
======================================================================

CUSTOMER SUBMITTED WORKAROUND :
Install a delegate. The same delegate will work for all enum types.

import java.util.*;
import java.beans.*;

class EnumDelegate extends DefaultPersistenceDelegate
{
   protected Expression instantiate(Object oldInstance, Encoder out)
   {
      return new Expression(Enum.class,
         "valueOf",
         new Object[] { oldInstance.getClass(), ((Enum) oldInstance).name() });
   }
   protected boolean mutatesTo(Object oldInstance, Object newInstance)
   {
      return oldInstance == newInstance;
   }
}

With this workaround, this test case
<test case>
enum Mood { SAD, HAPPY };

public class Test2
{
   public static void main(String[] args)
   {
      XMLEncoder out = new XMLEncoder(System.out);
      out.setPersistenceDelegate(Mood.class, new EnumDelegate());
      out.writeObject(Mood.SAD);
      out.close();
   }
}
</test case>


should write an expression that encodes Mood.SAD such as

<object class="java.lang.Enum" method="valueOf">
  <class>Mood</class>
  <string>SAD</string>
 </object>

###@###.### 2004-09-02

                                    

Comments
EVALUATION

Name: sh120115			Date: 04/07/2004

Interesting...we need to investigate how XMLEncoder/XMLDecoder will support enumerations.
###@###.### 2004-04-07

======================================================================

FWIW, this also doesn't work with the pre-1.5 typesafe enum pattern.
###@###.### 2004-04-09

I think this is indicative of a more general problem with immutable static object fields.  Other examples are SystemColor and BigInteger.  These also are not written out when added as properties to a Bean.
###@###.### 2004-04-14

We need to introduce support for both of these structures.
###@###.### 2005-06-06 15:43:55 GMT
                                     
2004-04-14
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
dragon


                                     
2004-09-04



Hardware and Software, Engineered to Work Together