JDK-6882911 : LTP: JDK7 breaks backward compatibility with XMLEncoder
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.beans
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2009-09-17
  • Updated: 2011-02-16
  • Resolved: 2009-11-23
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
JDK 7 M4 - 1.7.0-ea

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
JDK7 breaks backward compatibility with XMLEncoder. XMLEncoder stopped to cache persistence delegates => property is not serialized. A lot of existing applications rely on it.
See a test case code.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run test case on different versions JDK - JDK 6 and JDK 7
It will produce different output results.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
JDK 6 result:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.6.0_14" class="java.beans.XMLDecoder">
 <object class="TestEncoder$TestBean">
  <void property="url">
   <object class="java.net.URL">
    <string>http://test</string>
   </object>
  </void>
 </object>
</java>
ACTUAL -
JDK 7 result:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0-ea" class="java.beans.XMLDecoder">
</java>

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.beans.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
 
public class TestEncoder {
    public static void main(String[] args) throws IOException {
        XMLEncoder e = new XMLEncoder(System.out);
        e.setPersistenceDelegate(URL.class, new PrimitivePersistenceDelegate());
        e = new XMLEncoder(System.out);//intention
        final TestBean bean = new TestBean();
        try {
            bean.setUrl(new URL("http://test"));
        } catch (MalformedURLException e1) {
            e1.printStackTrace();
        }
        final MyExceptionListener exListener = new MyExceptionListener();
        e.setExceptionListener(exListener);
        e.writeObject(bean);
        if (exListener.ex != null)
            throw new IOException("XMLEnc failed", exListener.ex);
        e.close();
    }
 
 
    static class PrimitivePersistenceDelegate extends PersistenceDelegate {
 
        protected Expression instantiate(Object oldInstance, Encoder out) {
            return new Expression(oldInstance, oldInstance.getClass(),
                    "new", new Object[]{oldInstance.toString()});
        }
    }
 
    private static class MyExceptionListener implements ExceptionListener {
        Exception ex;
 
        public void exceptionThrown(Exception e) {
            if (this.ex == null)
                this.ex = e;
        }
    }
 
    public static class TestBean {
        private URL url;
 
        public TestBean() {
 
        }
 
        public URL getUrl() {
            return url;
        }
 
        public void setUrl(URL url) {
            this.url = url;
        }
    }
 
 
}

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

CUSTOMER SUBMITTED WORKAROUND :
Setting all persistence delegates you need for every instance of XMLEncoder.

Release Regression From : 6
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

Comments
EVALUATION Javadoc for the setPersistenceDelegate method says nothing about static nature for method behavior. This is non-static method and applications should not rely on it's unexpected behavior.
23-11-2009