Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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.
  • Loading branch information...
commit 17e18fe177d8661cae4d9e08c5a9ef3610000217 1 parent 003f12c
@rolfl rolfl authored
View
16 core/src/java/org/jdom2/CloneBase.java
@@ -61,6 +61,22 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* @author Rolf Lear
*/
class CloneBase implements Cloneable {
+
+ /**
+ * Change the permission of the no-arg constructor from public to protcted.
+ * <p>
+ * Otherwise package-private class's constructor is not really public. Changing this to
+ * 'protected' makes this constructor available to all subclasses regardless of the
+ * subclass's package. This in turn makes it possible to make all th subclasses of this
+ * CloneBase class serializable.
+ *
+ */
+ protected CloneBase() {
+ // This constructor is needed to solve issue #88
+ // There needs to be a no-arg constructor accessible by all
+ // potential subclasses of CloneBase, and 'protected' is actually more
+ // accessible than 'public' since this is a package-private class.
+ }
/**
* Return a deep clone of this instance. Even if this instance has a parent,
View
10 test/src/java/org/jdom2/test/cases/serialize/SAttribute.java
@@ -0,0 +1,10 @@
+package org.jdom2.test.cases.serialize;
+
+import org.jdom2.Attribute;
+
+@SuppressWarnings("javadoc")
+public class SAttribute extends Attribute {
+
+ private static final long serialVersionUID = 1L;
+
+}
View
10 test/src/java/org/jdom2/test/cases/serialize/SCDATA.java
@@ -0,0 +1,10 @@
+package org.jdom2.test.cases.serialize;
+
+import org.jdom2.CDATA;
+
+@SuppressWarnings("javadoc")
+public class SCDATA extends CDATA {
+
+ private static final long serialVersionUID = 1L;
+
+}
View
10 test/src/java/org/jdom2/test/cases/serialize/SComment.java
@@ -0,0 +1,10 @@
+package org.jdom2.test.cases.serialize;
+
+import org.jdom2.Comment;
+
+@SuppressWarnings("javadoc")
+public class SComment extends Comment {
+
+ private static final long serialVersionUID = 1L;
+
+}
View
10 test/src/java/org/jdom2/test/cases/serialize/SDocType.java
@@ -0,0 +1,10 @@
+package org.jdom2.test.cases.serialize;
+
+import org.jdom2.DocType;
+
+@SuppressWarnings("javadoc")
+public class SDocType extends DocType {
+
+ private static final long serialVersionUID = 1L;
+
+}
View
10 test/src/java/org/jdom2/test/cases/serialize/SElement.java
@@ -0,0 +1,10 @@
+package org.jdom2.test.cases.serialize;
+
+import org.jdom2.Element;
+
+@SuppressWarnings("javadoc")
+public class SElement extends Element {
+
+ private static final long serialVersionUID = 1L;
+
+}
View
10 test/src/java/org/jdom2/test/cases/serialize/SEntityRef.java
@@ -0,0 +1,10 @@
+package org.jdom2.test.cases.serialize;
+
+import org.jdom2.EntityRef;
+
+@SuppressWarnings("javadoc")
+public class SEntityRef extends EntityRef {
+
+ private static final long serialVersionUID = 1L;
+
+}
View
18 test/src/java/org/jdom2/test/cases/serialize/SFilter.java
@@ -0,0 +1,18 @@
+package org.jdom2.test.cases.serialize;
+
+import org.jdom2.filter.AbstractFilter;
+
+@SuppressWarnings("javadoc")
+public class SFilter extends AbstractFilter<Integer> {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public Integer filter(Object content) {
+ if (content instanceof Integer) {
+ return (Integer)content;
+ }
+ return null;
+ }
+
+}
View
10 test/src/java/org/jdom2/test/cases/serialize/SProcessingInstruction.java
@@ -0,0 +1,10 @@
+package org.jdom2.test.cases.serialize;
+
+import org.jdom2.ProcessingInstruction;
+
+@SuppressWarnings("javadoc")
+public class SProcessingInstruction extends ProcessingInstruction {
+
+ private static final long serialVersionUID = 1L;
+
+}
View
10 test/src/java/org/jdom2/test/cases/serialize/SText.java
@@ -0,0 +1,10 @@
+package org.jdom2.test.cases.serialize;
+
+import org.jdom2.Text;
+
+@SuppressWarnings("javadoc")
+public class SText extends Text {
+
+ private static final long serialVersionUID = 1L;
+
+}
View
55 test/src/java/org/jdom2/test/cases/serialize/TestSubclassSerializables.java
@@ -0,0 +1,55 @@
+package org.jdom2.test.cases.serialize;
+
+import static org.jdom2.test.util.UnitTestUtil.deSerialize;
+
+import org.junit.Test;
+
+@SuppressWarnings("javadoc")
+public class TestSubclassSerializables {
+
+ @Test
+ public void testFilter() {
+ deSerialize(new SFilter());
+ }
+
+ @Test
+ public void testAttribute() {
+ deSerialize(new SAttribute());
+ }
+
+ @Test
+ public void testCDATA() {
+ deSerialize(new SComment());
+ }
+
+ @Test
+ public void testComment() {
+ deSerialize(new SComment());
+ }
+
+ @Test
+ public void testDocType() {
+ deSerialize(new SDocType());
+ }
+
+ @Test
+ public void testElement() {
+ deSerialize(new SElement());
+ }
+
+ @Test
+ public void testEntityRef() {
+ deSerialize(new SEntityRef());
+ }
+
+ @Test
+ public void testProcessingInstruction() {
+ deSerialize(new SProcessingInstruction());
+ }
+
+ @Test
+ public void testText() {
+ deSerialize(new SText());
+ }
+
+}
View
28 test/src/java/org/jdom2/test/util/UnitTestUtil.java
@@ -118,11 +118,11 @@ public static final void testNamespaceScope(NamespaceAware content, Namespace...
* @param input
* @return
*/
- public static final <T extends Serializable> T deSerialize(T input) {
+ public static final <T extends Serializable> T deSerialize(final T input) {
if (input == null) {
return null;
}
- Class<?> tclass = input.getClass();
+ final Class<?> tclass = input.getClass();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
final ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
@@ -130,26 +130,26 @@ public static final void testNamespaceScope(NamespaceAware content, Namespace...
objectOutputStream.writeObject(input);
}
catch(final IOException ioException) {
- failException("Unable to serialize object" + ioException, ioException);
+ failException("Unable to serialize object.", ioException);
}
finally {
try {
objectOutputStream.close();
}
catch(final IOException ioException) {
- fail("failed to close object stream while serializing object" + ioException);
+ failException("failed to close object stream while serializing object", ioException);
}
}
}
catch(final IOException ioException) {
- fail("unable to serialize object" + ioException);
+ failException("unable to serialize object", ioException);
}
finally {
try {
outputStream.close();
}
catch(final IOException ioException) {
- fail("failed to close output stream while serializing object" + ioException);
+ failException("failed to close output stream while serializing object", ioException);
}
}
@@ -168,27 +168,33 @@ public static final void testNamespaceScope(NamespaceAware content, Namespace...
objectInputStream.close();
}
catch(final IOException ioException) {
- fail("failed to close object stream while deserializing object" + ioException);
+ failException("failed to close object stream while deserializing object", ioException);
}
}
}
catch(final IOException ioException) {
- fail("unable to deserialize object" + ioException);
+ failException("unable to deserialize object.", ioException);
}
catch(final ClassNotFoundException classNotFoundException) {
- fail("unable to deserialize object" + classNotFoundException);
+ failException("unable to deserialize object.", classNotFoundException);
}
finally {
try{
inputStream.close();
}
catch(final IOException ioException) {
- fail("failed to close output stream while serializing object" + ioException);
+ failException("failed to close output stream while serializing object.", ioException);
}
}
+ assertTrue("Deserialized (non-null) object is null!", o != null);
+
@SuppressWarnings("unchecked")
- T t = (T)tclass.cast(o);
+ final T t = (T)tclass.cast(o);
+
+ assertTrue("Deserialized instance should not be the same instance as the pre-serialization",
+ t != input);
+
return t;
}
Please sign in to comment.
Something went wrong with that request. Please try again.