Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom JDOM subclasses are not serializable #88

Closed
rolfl opened this issue Aug 9, 2012 · 0 comments
Closed

Custom JDOM subclasses are not serializable #88

rolfl opened this issue Aug 9, 2012 · 0 comments

Comments

@rolfl
Copy link
Collaborator

rolfl commented Aug 9, 2012

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

@rolfl rolfl closed this as completed in 17e18fe Aug 11, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant