1

The XMLEncoder contructor init state optimization is great, except when you need it to encode the actual state set following some state set by the constructor. This seems to be a bug (or missing feature :-)).

import java.beans.Encoder;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
import java.beans.XMLEncoder;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class XMLEncoderBug {
    private File file;

    public XMLEncoderBug() {
        //this.setFile(".");
    }

    public File getFile() {
        return this.file;
    }

    public void setFile(String fileName) {
        this.setFile(new File(fileName));
    }

    public void setFile(File file) {
        this.file = file;
    }

    public static void main(String[] args) throws IOException {
        XMLEncoderBug bean = new XMLEncoderBug();
        bean.setFile(new File("./test/test/test"));

        FileOutputStream fout = new FileOutputStream("TestBean.xml");
        XMLEncoder enc = new XMLEncoder(fout);

        enc.setPersistenceDelegate(File.class, new PersistenceDelegate() {
            protected Expression instantiate(Object oldInstance, Encoder out) {
                System.out.printf("FilePersistenceDelegate.instantiate(oldInstance=%s, out)\n", oldInstance.getClass().getName());
                File file = (File)oldInstance;
                String fileName = file.getAbsolutePath();

                return new Expression(file, file.getClass(), "new", new Object[]{ fileName });
            }
        });

        enc.writeObject(bean);
        enc.flush();
        fout.flush();
        enc.close();
        fout.close();
    }
}

So, run the code as is. Everything encodes as expected. Then, un-comment the line in the constructor and run it again. Note how the actual state of the bean is not persisted properly.

Now, I understand the optimization of XMLEncoder not to encode any state set by a no-arg constructor, because there is no need since during decoding, the constructor is invoked and the state initialized to whatever the constructor does.

But, when the state is initialized in some way by the constructor and subsequently changed, the persisted state of the instance is definitely not being encoded correctly.

Am I missing something?

BTW: Java 1.8.

JMorgan
  • 85
  • 1
  • 11
  • Could you please define exactly *how* it is "encoded incorrectly"? Exactly what is the output you expect without the call to `setFile()`? – Bohemian Feb 03 '19 at 23:58
  • Depends on which setFile() call you are referencing. There is a setFile(..) in main, and a commented setFile() in the constructor. As is above, everything encodes correctly. that is, you can clearly see in the output XML the file name persisted. But, uncomment the setFile() in the constructor, and no longer do you see the file name persisted, and, in fact, I would think it should be considering the setFile(..) in main changes the state of the bean. – JMorgan Feb 05 '19 at 00:14

0 Answers0