Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8366180

XMLEncoder fails to serialize javax.swing.border.LineBorder properties

XMLWordPrintable

    • generic
    • generic

      A DESCRIPTION OF THE PROBLEM :
      When XMLEncoder.writeObject() a bean containing a javax.swing.border.LineBorder whose lineColor is null (or any non-default combination), the resulting XML omits all of the border’s state. On decode it fall back to the bean’s default LineBorder. Even registering a PersistenceDelegate( "lineColor","thickness","roundedCorners" ) for LineBorder has no effect

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      successfully serialize Bean and its value(a LineBorader).
      ACTUAL -
      <?xml version="1.0" encoding="UTF-8"?>
      <java version="24.0.1" class="java.beans.XMLDecoder">
       <object class="LineBorderXMLSerializationTest$Bean"/>
      </java>

      Exception in thread "main" java.lang.RuntimeException: Color mismatch: original=null, deserialized=java.awt.Color[r=255,g=0,b=0]
      at LineBorderXMLSerializationTest.main(LineBorderXMLSerializationTest.java:63)


      ---------- BEGIN SOURCE ----------
      import javax.swing.border.LineBorder;
      import java.awt.Color;
      import java.beans.*;
      import java.io.ByteArrayInputStream;
      import java.io.ByteArrayOutputStream;
      import java.io.IOException;
      import java.nio.charset.StandardCharsets;
      import java.util.Objects;

      public class LineBorderXMLSerializationTest {

          public static class Bean {
              public final static LineBorder DEFAULT = new LineBorder(Color.RED, 2, true);
              private LineBorder value;
              public Bean() {this.value = DEFAULT;}
              public LineBorder getValue() {return value;}
              public void setValue(LineBorder value) {this.value = value;}
          }

          public static void main(String[] args) throws IOException {
              LineBorder originalBorder = new LineBorder(null, 0, false);

              Bean beanToEncode = new Bean();
              beanToEncode.setValue(originalBorder);

              ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
              try (XMLEncoder encoder = new XMLEncoder(outputStream)) {
                  encoder.setPersistenceDelegate(
                      LineBorder.class,
                      new PersistenceDelegate() {
                          @Override
                          protected Expression instantiate(Object oldInstance, Encoder out) {
                              LineBorder lb = (LineBorder) oldInstance;
                              return new Expression(
                                      lb,
                                      lb.getClass(),
                                      "new",
                                      new Object[]{lb.getLineColor(),
                                              lb.getThickness(),
                                              lb.getRoundedCorners()}
                              );
                          }
                      }
                  );
                  encoder.writeObject(beanToEncode);
              }

              byte[] xmlData = outputStream.toByteArray();


              System.out.println(new String(xmlData, StandardCharsets.UTF_8));

              Bean deserializedBean;
              ByteArrayInputStream inputStream = new ByteArrayInputStream(xmlData);
              try (XMLDecoder decoder = new XMLDecoder(inputStream)) {
                  deserializedBean = (Bean) decoder.readObject();
              }

              LineBorder deserializedBorder = deserializedBean.getValue();
              Color originalColor = originalBorder.getLineColor();
              Color deserializedColor = deserializedBorder.getLineColor();
              if (!Objects.equals(originalColor, deserializedColor)) {
                  throw new RuntimeException("Color mismatch: original=" + originalColor + ", deserialized=" + deserializedColor);
              } else {
                  System.out.println("\nColors match.");
              }
          }
      }
      ---------- END SOURCE ----------

      Workaround
      following way can get correct result
      encoder.setPersistenceDelegate(
        Bean.class,
        new PersistenceDelegate() {
          @Override
          protected Expression instantiate(Object old, Encoder out) {
            return new Expression(old, old.getClass(), "new", new Object[]{});
          }
          @Override
          protected void initialize(Class<?> type, Object old, Object existing, Encoder out) {
            super.initialize(type, old, existing, out);
            Bean bOld = (Bean) old;
            if (bOld.getValue() != ((Bean) existing).getValue()) {
              out.writeStatement(
                new Statement(old, "setValue", new Object[]{ bOld.getValue() })
              );
            }
          }
        }
      );

            psadhukhan Prasanta Sadhukhan
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: