Skip to content
This repository

Custom JDOM subclasses are not serializable #88

Closed
rolfl opened this Issue · 0 comments

1 participant

Rolf
Rolf
Collaborator

Hi Björn, Oliver

I have identified what the problem is...... this is not actually a Java bug, but it describes what the potential JDOM bug is... I think....

http://bugs.sun.com/view_bug.do?bug_id=6522514

What this implies is that there is an issue in the permissions of the JDOM element hierarchy.

in my understanding, it goes like this....

org.jdom2.Element extends org.jdom2.Content.
org.jdom2.Content extends org.jdom2.CloneBase.
org.jdom2.CloneBase is a package-private (not public) class, and CloneBase has no declared constructor (it has the default no-arg constructor).

Your class 'MyElement' is not in the org.jdom2 package, so, it cannot 'see' the no-arg constructor for (package private) org.jdom2.CloneBase.

Thus the MyElement class cannot be de-serialized.

I have 'proven' that this is the logic fault by putting the MyElement class in the org.jdom2 package, and then, miraculously, the code works. When I get home I will try it again but instead with a 'protected' no-arg constructor on org.jdom2.CloneBase, and the MyElement class in some other package..... actually, I have just tried it now, and it works.....

Thus, there are two work-arounds:

  • putting your MyElement code in the org.jdom2 package....
  • using the attached org.jdom2.CloneBase class which has a protected no-arg constructor.

I have created a new issue, and I have attached a working CloneBase class you can add to your project temporarily.....

I will push out JDOM 2.0.3

Rolf

On Thu, 9 Aug 2012 11:03:52 -0400, Oliver Ruebenacker curoli@gmail.com
wrote:

Hello,

Rolf, it shouldn't be necessary to add these methods.

Björn, can you check the import statement for Element?

 Take care
 Oliver

On Thu, Aug 9, 2012 at 10:37 AM, Rolf Lear jdom@tuis.net wrote:

Hi Björn

I don't have my 'JDOM Laptop' with me at the moment, so I can't easily
reproduce your problem, but, I suspect this is just an issue of
implementing your own read/write object methods.

What happens if you add the following methods to your 'MyElement' class?
I
believe this should fix things..... try it... :-)

    /**
     * Serialize out the MyElement.
     *
     * @serialData
     * The Stream protocol is:
     * <ol>
     *   <li>Write the super Element class out...
     * </ol>
     *
     * @param out where to write the Element to.
     * @throws IOException if there is a writing problem.
     */
    private void writeObject(final ObjectOutputStream out) throws
    IOException

{
out.defaultWriteObject();
}

    /**
     * Read a MyElement off the ObjectInputStream.
     *
     * @see #writeObject(ObjectOutputStream)
     * @param in where to read the Element from.
     * @throws IOException if there is a reading problem.
     * @throws ClassNotFoundException when a class cannot be found
     */
    private void readObject(final ObjectInputStream in)
                    throws IOException, ClassNotFoundException {
            in.defaultReadObject();
    }

Rolf

On Thu, 09 Aug 2012 16:08:48 +0200, Björn Buchner
b.buchner@isys-software.de wrote:

Hi Folks,

I am using the JDOM 2.0.2 release and experienced some trouble when it
comes to serialization.

De-/serializing an Element object through the standard
ObjectOutput/InputStream is no problem. Trouble starts when I try to
deserialize an object of a class that inherits from Element.

It always ends with a InvalidClassException: no valid constructor.
Normally this indicates that JRE is missing a public default
constructor, but as you can see in the example below the subclass
has a default constructor.

Thanks in advance for your help

Example code:

public class MyElement extends Element {

 private static final long serialVersionUID = -4220756491425652053L;

 public MyElement() {
     super();
 }


 public static void main(String ... args) throws IOException,

ClassNotFoundException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ObjectOutputStream outStream = new ObjectOutputStream(buffer);

    MyElement element = new MyElement();

    outStream.writeObject(element);
    outStream.flush();
    ObjectInputStream inStream = new ObjectInputStream(new

ByteArrayInputStream(buffer.toByteArray()));
element = (MyElement)inStream.readObject();
}
}

Result:

Exception in thread "main" java.io.InvalidClassException:
; no valid constructor
at

java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(ObjectStreamClass.java:147)
at
java.io.ObjectStreamClass.checkDeserialize(ObjectStreamClass.java:755)
at

java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1751)
at
java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at .main(MyElement.java:29)


To control your jdom-interest membership:
http://www.jdom.org/mailman/options/jdom-interest/youraddr@yourhost.com

Rolf rolfl closed this issue from a commit
Rolf Fixes #88 - broken serialization of subclasses of core JDOM classes (…
…like custom subclasses of Element).

Upgrade the serialiazion test-code to report exceptions better.
Add a test-case that checks that all subclasses are serializable.
17e18fe
Rolf rolfl closed this in 17e18fe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.