Log Message
Fix NPE if SerializationConverter.canConvert(type) is called with an interface type as argument that extends Serializable (XSTR-753).
Modified Paths
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializableConverter.java
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java
- trunk/xstream/src/test/com/thoughtworks/acceptance/annotations/AttributesTest.java
- trunk/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SerializableConverterTest.java
- trunk/xstream-distribution/src/content/changes.html
Diff
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializableConverter.java (2237 => 2238)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializableConverter.java 2014-01-29 01:06:19 UTC (rev 2237)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializableConverter.java 2014-01-30 01:16:51 UTC (rev 2238)
@@ -104,10 +104,12 @@
}
private boolean isSerializable(Class type) {
- if (Serializable.class.isAssignableFrom(type)
- && ( serializationMethodInvoker.supportsReadObject(type, true)
- || serializationMethodInvoker.supportsWriteObject(type, true) )) {
- for(Iterator iter = hierarchyFor(type).iterator(); iter.hasNext(); ) {
+ if (type != null
+ && Serializable.class.isAssignableFrom(type)
+ && !type.isInterface()
+ && (serializationMethodInvoker.supportsReadObject(type, true) || serializationMethodInvoker
+ .supportsWriteObject(type, true))) {
+ for (Iterator iter = hierarchyFor(type).iterator(); iter.hasNext();) {
if (!Serializable.class.isAssignableFrom((Class)iter.next())) {
return canAccess(type);
}
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java (2237 => 2238)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java 2014-01-29 01:06:19 UTC (rev 2237)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java 2014-01-30 01:16:51 UTC (rev 2238)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2004, 2005 Joe Walnes.
- * Copyright (C) 2006, 2007, 2008, 2010, 2011 XStream Committers.
+ * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2014 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -153,6 +153,9 @@
}
private Method getMethod(Class type, String name, Class[] parameterTypes) {
+ if (type == null) {
+ return null;
+ }
FastField method = new FastField(type, name);
Method result = (Method)cache.get(method);
Modified: trunk/xstream/src/test/com/thoughtworks/acceptance/annotations/AttributesTest.java (2237 => 2238)
--- trunk/xstream/src/test/com/thoughtworks/acceptance/annotations/AttributesTest.java 2014-01-29 01:06:19 UTC (rev 2237)
+++ trunk/xstream/src/test/com/thoughtworks/acceptance/annotations/AttributesTest.java 2014-01-30 01:16:51 UTC (rev 2238)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 XStream Committers.
+ * Copyright (C) 2007, 2014 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -10,10 +10,14 @@
*/
package com.thoughtworks.acceptance.annotations;
+import java.io.Serializable;
+
import com.thoughtworks.acceptance.AbstractAcceptanceTest;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+import com.thoughtworks.xstream.converters.extended.ToStringConverter;
/**
@@ -59,4 +63,63 @@
String expected = "<annotated field=\"hello\"/>";
assertBothWays(value, expected);
}
+
+ @XStreamAlias("annotated")
+ public static class AnnotatedAttributeParameterized<T> implements Serializable {
+ @XStreamAsAttribute
+ private String myField;
+ }
+
+ public void testAnnotationInParameterizedClass() {
+ AnnotatedAttributeParameterized<String> value = new AnnotatedAttributeParameterized<String>();
+ value.myField = "hello";
+ String expected = "<annotated myField=\"hello\"/>";
+ assertBothWays(value, expected);
+ }
+
+ @XStreamAlias("annotated")
+ public static class AnnotatedGenericAttributeParameterized<T> implements Serializable {
+ @XStreamAsAttribute
+ private T myField;
+ }
+
+ public void testAnnotationAtGenericTypeInParameterizedClass() {
+ AnnotatedGenericAttributeParameterized<String> value = new AnnotatedGenericAttributeParameterized<String>();
+ value.myField = "hello";
+ String expected = ""
+ + "<annotated>\n"
+ + " <myField class=\"string\">hello</myField>\n"
+ + "</annotated>";
+ assertBothWays(value, expected);
+ }
+
+ @XStreamAlias("annotated")
+ public static class AnnotatedGenericAttributeBounded<T extends Serializable> implements Serializable {
+ @XStreamAsAttribute
+ private T myField;
+ }
+
+ public void testAnnotationAtGenericTypeInBoundedClass() {
+ AnnotatedGenericAttributeBounded<String> value = new AnnotatedGenericAttributeBounded<String>();
+ value.myField = "hello";
+ String expected = ""
+ + "<annotated>\n"
+ + " <myField class=\"string\">hello</myField>\n"
+ + "</annotated>";
+ assertBothWays(value, expected);
+ }
+
+ @XStreamAlias("annotated")
+ public static class AnnotatedGenericAttributeAndConverterParameterized<T> implements Serializable {
+ @XStreamAsAttribute
+ @XStreamConverter(value=ToStringConverter.class, useImplicitType=false, types={String.class})
+ private T myField;
+ }
+
+ public void testAnnotationAtGenericTypeWithLocalConverterInParameterizedClass() {
+ AnnotatedGenericAttributeAndConverterParameterized<String> value = new AnnotatedGenericAttributeAndConverterParameterized<String>();
+ value.myField = "hello";
+ String expected = "<annotated myField=\"hello\"/>";
+ assertBothWays(value, expected);
+ }
}
Modified: trunk/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SerializableConverterTest.java (2237 => 2238)
--- trunk/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SerializableConverterTest.java 2014-01-29 01:06:19 UTC (rev 2237)
+++ trunk/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SerializableConverterTest.java 2014-01-30 01:16:51 UTC (rev 2238)
@@ -325,4 +325,28 @@
SimpleNamedFieldsType serialized = (SimpleNamedFieldsType)xstream.fromXML(xml);
assertEquals(simple, serialized);
}
+
+ public static class SerializableType implements Serializable {
+ public Serializable serializable;
+ }
+
+ public void testCanHandleFieldsDeclaredWithSerializableInterface() {
+ XStream xstream = new XStream();
+ xstream.allowTypes(SerializableType.class);
+ xstream.alias("sertype", SerializableType.class);
+ xstream.useAttributeFor(SerializableType.class, "serializable");
+
+ String expected = ""
+ + "<sertype>\n"
+ + " <serializable class=\"string\">String</serializable>\n"
+ + "</sertype>";
+
+ SerializableType s = new SerializableType();
+ s.serializable = "String";
+
+ String xml = xstream.toXML(s);
+ assertEquals(expected, xml);
+ SerializableType serialized = (SerializableType)xstream.fromXML(xml);
+ assertEquals(s.serializable, serialized.serializable);
+ }
}
Modified: trunk/xstream-distribution/src/content/changes.html (2237 => 2238)
--- trunk/xstream-distribution/src/content/changes.html 2014-01-29 01:06:19 UTC (rev 2237)
+++ trunk/xstream-distribution/src/content/changes.html 2014-01-30 01:16:51 UTC (rev 2238)
@@ -75,6 +75,8 @@
<ul>
<li>XSTR-749: NPE if ReflectionConverter.canConvert(type) is called with null as argument.</li>
+ <li>XSTR-753: NPE if SerializationConverter.canConvert(type) is called with an interface type as argument that
+ extends Serializable.</li>
<li>Add constructor to ReflectionConverter taking an additional type to create an instance that is
dedicated to a specific type only.</li>
<li>The ConverterLookup used by default cannot be casted to a ConverterRegistry anymore.</li>
To unsubscribe from this list please visit:
