This discussion is archived
3 Replies Latest reply: Aug 17, 2010 1:32 AM by 843790 RSS

java.beans.XMLEncoder doesn't writes out id. Why?

843790 Newbie
Currently Being Moderated
Hi,

the problem seems to be that my interface (see code below) defines a getter with a super type.
Even specifying the correct subtype in the class, still prevents XMLEncoder from recognising it as a property.

Cause I need the interface for polymorphism and I also have other ID's than Long (natural keys), I can't get rid of the interface or the super type. Even specifying a second interface, like this:
public interface SupportsDatabaseLongId extends SupportsDatabaseId {
    @Override
    public Long getId();

    public void setId(final Long id);
}
doesn't solve the problem.

Also a generic interface
public interface SupportsDatabaseId<T extends Serializable> extends Serializable {
    public T getId();
}
with this declaration
public class Test_IDS_with_XML_Encoder implements SupportsDatabaseId<Long> 
doesn't solve it neither. Which isn't really surprising, cause type erasing would reduce it to Serializable again.


Cause of the huge amount of classes which are using this interface, I can't write a persistence delegate for each of them. Any ideas to fix this smoothly?

The only idea I have is to avoid the naming problem, like this
public interface SupportsDatabaseId extends Serializable {
    public Serializable getDatabaseId();
}
which leads to code duplication like this.
 /*
     * (non-Javadoc)
     * 
     * @see de.zew.vitax.database.SupportsDatabaseId#getDatabaseId()
     */
    @Override
    public Serializable getDatabaseId() {
     return getId();
    }
But at lest not the worst solution, i can think of.

Thanks.

Greetings Michael

SSCCE
public interface SupportsDatabaseId extends Serializable {
    public Serializable getId();
}
import java.beans.ExceptionListener;
import java.beans.XMLEncoder;
import java.io.*;

public class Test_IDS_with_XML_Encoder implements SupportsDatabaseId {

    /* Target filename */
    private static final String targetFilename = ".\\TestPdfs\\enc_out.xml";

    public static void main(final String args[]) {
     openXMLEncoder(new File(targetFilename));
     System.exit(0);
    }

    private static void openXMLEncoder(final File file) {
     FileOutputStream fos = null;
     BufferedOutputStream out = null;
     XMLEncoder enc = null;

     try {
         if (file != null) {
          System.out.println(file.getAbsolutePath());
          if (file.exists()) {
              file.delete();
          }
          file.createNewFile();
          if (file.canWrite()) {

              fos = new FileOutputStream(file);
              out = new BufferedOutputStream(fos);
              enc = new XMLEncoder(new BufferedOutputStream(fos));

              enc.setExceptionListener(new ExceptionListener() {
               /*                                                               * Avoid multiple popups of error warnings */
               public void exceptionThrown(final Exception e) {
                   e.printStackTrace();
               }
              });

              for (int i = 0; i < 10; i++) {
               enc.writeObject(new Test_IDS_with_XML_Encoder(new Long(i)));
              }
              enc.close();
          }

         }
     }
     catch (final Throwable e) {
         e.printStackTrace();
     }
     finally {
         if (enc != null) {
          enc.close();
         }
         if (out != null) {
          try {
              out.close();
          }
          catch (final IOException ioe) {
              ioe.printStackTrace();
          }
         }
         if (fos != null) {
          try {
              fos.close();
          }
          catch (final IOException ioe) {
              ioe.printStackTrace();
          }
         }

     }
    }

    protected Long id;

    public Test_IDS_with_XML_Encoder() {
    }

    Test_IDS_with_XML_Encoder(final Long id) {
     this.id = id;
    }

    /**
     * @return the id
     */
    public Long getId() {
     return this.id;
    }

    /**
     * @param id
     *            the id to set
     */
    public void setId(final Long id) {
     this.id = id;
    }
}
This produces this output:
?xml version="1.0" encoding="UTF-8"?> 
<java version="1.6.0_20" class="java.beans.XMLDecoder"> 
 <object class="test.Test_IDS_with_XML_Encoder"/> 
 <object class="test.Test_IDS_with_XML_Encoder"/> 
 <object class="test.Test_IDS_with_XML_Encoder"/> 
 <object class="test.Test_IDS_with_XML_Encoder"/> 
 <object class="test.Test_IDS_with_XML_Encoder"/> 
 <object class="test.Test_IDS_with_XML_Encoder"/> 
 <object class="test.Test_IDS_with_XML_Encoder"/> 
 <object class="test.Test_IDS_with_XML_Encoder"/> 
 <object class="test.Test_IDS_with_XML_Encoder"/> 
 <object class="test.Test_IDS_with_XML_Encoder"/> 
</java> 
Desired output and retrieved without interface implementation:
<?xml version="1.0" encoding="UTF-8"?> 
<java version="1.6.0_20" class="java.beans.XMLDecoder"> 
 <object class="test.Test_IDS_with_XML_Encoder"> 
  <void property="id"> 
   <long>0</long> 
  </void> 
 </object> 
 <object class="test.Test_IDS_with_XML_Encoder"> 
  <void property="id"> 
   <long>1</long> 
  </void> 
 </object> 
 <object class="test.Test_IDS_with_XML_Encoder"> 
  <void property="id"> 
   <long>2</long> 
  </void> 
 </object> 
 <object class="test.Test_IDS_with_XML_Encoder"> 
  <void property="id"> 
   <long>3</long> 
  </void> 
 </object> 
 <object class="test.Test_IDS_with_XML_Encoder"> 
  <void property="id"> 
   <long>4</long> 
  </void> 
 </object> 
 <object class="test.Test_IDS_with_XML_Encoder"> 
  <void property="id"> 
   <long>5</long> 
  </void> 
 </object> 
 <object class="test.Test_IDS_with_XML_Encoder"> 
  <void property="id"> 
   <long>6</long> 
  </void> 
 </object> 
 <object class="test.Test_IDS_with_XML_Encoder"> 
  <void property="id"> 
   <long>7</long> 
  </void> 
 </object> 
 <object class="test.Test_IDS_with_XML_Encoder"> 
  <void property="id"> 
   <long>8</long> 
  </void> 
 </object> 
 <object class="test.Test_IDS_with_XML_Encoder"> 
  <void property="id"> 
   <long>9</long> 
  </void> 
 </object> 
</java> 
Edited by: Urmech on Aug 12, 2010 6:13 AM
  • 1. Re: java.beans.XMLEncoder doesn't writes out id. Why?
    800330 Explorer
    Currently Being Moderated
    Michael, you seem to be running into a lot of trouble using XMLEncoder. Is it still worth while? You mentioned somewhere that you plan to use the XML serialization for some sort of short term persistence while the instances involved will also be stored in a database. Why the short term storage? And if so required, could any of the other XML marshalling frameworks (isn't one called JAXB? Yes it is, and some people ["swear up and down" over it|http://stackoverflow.com/questions/607141/what-is-jaxb-and-why-would-i-use-it] ...) be of help?

    Just glanced at simple which has a very [ attractive introduction here|http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php] .

    Edited by: isocdev_mb on Aug 12, 2010 10:36 AM
  • 2. Re: java.beans.XMLEncoder doesn't writes out id. Why?
    843790 Newbie
    Currently Being Moderated
    Hi, thanks for your reply.

    Yes, XMLEncoder is only for short term persistence for user convince. Prior it was used as long term persistence, with all the known drawbacks. But cause it was quick and the original developer left shortly after implementing it, he didn't really cared about it or wasn't aware of it.

    But now it also has the nice side-effect, that you can rebuild the database without loss of data, as long as you keep one storage method unchanged. Or modify the XML-Persistence. One is an backup for the other. The choice of XML-Encoder is a historical issue, as mentioned above and was already in place, when I started to work on this project.

    Cause renaming or setting attributes transient solved my problems and the lack of remaining time (I'm leaving this project in a few days), it makes no sense to switch the XML-Implementation. But thanks, for the hint. Also most of the time, switching a framework may cure the one problem, but most likely raises other issue as well.

    *"Because it's so easy to do, there is a common misconception that serialization requires little effort of the programmer."*
    Efective Java2, Joshua Bloch page 289

    It's only a pitty, that the explanations how XMLEncoder works in detail aren't so well. cause it hasn't changed since 1.4, it is mostly that no one rally cares about it any more. Even the [EnumMap bug 6536295|http://download.java.net/jdk7/changes/jdk7-b20.html] seems to be fixed for Java7.

    Greetings Michael
  • 3. Re: java.beans.XMLEncoder doesn't writes out id. Why?
    843790 Newbie
    Currently Being Moderated
    New Problem occurred, if someone is interested on this new subject, you may look [here -- XML-Encoder ignores classes that have a Enum as property. Why?|http://forums.sun.com/thread.jspa?threadID=5447866]

    I solved it in the meantime, by setting an attribute transient, But still don't know why.

    I hope the JavaBeans-Forum may be the better place for this kind of stuff.

    Greetings Michael