Log Message
Merge fix for XSTR-762 into branch.
Modified Paths
- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java
- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java
- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java
- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/mapper/AbstractAttributeAliasingMapper.java
- branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/AbstractReferenceTest.java
- branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/SerializationCallbackOrderTest.java
- branches/v-1.4.x/xstream-distribution/src/content/changes.html
Diff
Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java (2301 => 2302)
--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java 2014-10-30 12:58:59 UTC (rev 2301)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java 2014-10-30 13:18:10 UTC (rev 2302)
@@ -53,7 +53,7 @@
public AbstractReflectionConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
this.mapper = mapper;
this.reflectionProvider = reflectionProvider;
- init();
+ serializationMethodInvoker = new SerializationMethodInvoker();
}
protected boolean canAccess(Class type) {
@@ -558,12 +558,8 @@
serializationMethodInvoker.flushCache();
}
- protected void init() {
+ protected Object readResolve() {
serializationMethodInvoker = new SerializationMethodInvoker();
- }
-
- private Object readResolve() {
- init();
return this;
}
Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java (2301 => 2302)
--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java 2014-10-30 12:58:59 UTC (rev 2301)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java 2014-10-30 13:18:10 UTC (rev 2302)
@@ -438,8 +438,8 @@
return typeHierarchy;
}
- private Object readResolve() {
- init();
+ protected Object readResolve() {
+ super.readResolve();
fieldCache = new HashMap();
return this;
}
Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java (2301 => 2302)
--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java 2014-10-30 12:58:59 UTC (rev 2301)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java 2014-10-30 13:18:10 UTC (rev 2302)
@@ -6,7 +6,7 @@
* The software in this package is published under the terms of the BSD
* style license a copy of which has been included with this distribution in
* the LICENSE.txt file.
- *
+ *
* Created on 23. August 2004 by Joe Walnes
*/
package com.thoughtworks.xstream.converters.reflection;
@@ -19,6 +19,7 @@
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -28,7 +29,7 @@
/**
* Convenience wrapper to invoke special serialization methods on objects (and perform
* reflection caching).
- *
+ *
* @author Joe Walnes
* @author Jörg Schaible
*/
@@ -39,17 +40,22 @@
}
}).getClass().getDeclaredMethods()[0];
private static final Object[] EMPTY_ARGS = new Object[0];
- private static final FastField[] OBJECT_TYPE_FIELDS = new FastField[]{
+ private static final Class[] EMPTY_CLASSES = new Class[0];
+ private static final FastField[] OBJECT_TYPE_FIELDS = {
new FastField(Object.class, "readResolve"),
new FastField(Object.class, "writeReplace"),
new FastField(Object.class, "readObject"),
new FastField(Object.class, "writeObject")
};
- private Map cache = Collections.synchronizedMap(new HashMap());
+ private Map declaredCache = Collections.synchronizedMap(new HashMap());
+ private Map resRepCache = Collections.synchronizedMap(new HashMap());
{
for(int i = 0; i < OBJECT_TYPE_FIELDS.length; ++i) {
- cache.put(OBJECT_TYPE_FIELDS[i], NO_METHOD);
+ declaredCache.put(OBJECT_TYPE_FIELDS[i], NO_METHOD);
}
+ for(int i = 0; i < 2; ++i) {
+ resRepCache.put(OBJECT_TYPE_FIELDS[i], NO_METHOD);
+ }
}
/**
@@ -59,17 +65,18 @@
if (result == null) {
return null;
} else {
- Method readResolveMethod = getMethod(result.getClass(), "readResolve", null, true);
+ final Class resultType = result.getClass();
+ final Method readResolveMethod = getRRMethod(resultType, "readResolve");
if (readResolveMethod != null) {
try {
return readResolveMethod.invoke(result, EMPTY_ARGS);
} catch (IllegalAccessException e) {
throw new ObjectAccessException("Could not call "
- + result.getClass().getName()
+ + resultType.getName()
+ ".readResolve()", e);
} catch (InvocationTargetException e) {
throw new ObjectAccessException("Could not call "
- + result.getClass().getName()
+ + resultType.getName()
+ ".readResolve()", e.getTargetException());
}
} else {
@@ -82,17 +89,18 @@
if (object == null) {
return null;
} else {
- Method writeReplaceMethod = getMethod(object.getClass(), "writeReplace", null, true);
+ final Class objectType = object.getClass();
+ final Method writeReplaceMethod = getRRMethod(objectType, "writeReplace");
if (writeReplaceMethod != null) {
try {
return writeReplaceMethod.invoke(object, EMPTY_ARGS);
} catch (IllegalAccessException e) {
throw new ObjectAccessException("Could not call "
- + object.getClass().getName()
+ + objectType.getName()
+ ".writeReplace()", e);
} catch (InvocationTargetException e) {
throw new ObjectAccessException("Could not call "
- + object.getClass().getName()
+ + objectType.getName()
+ ".writeReplace()", e.getTargetException());
}
} else {
@@ -157,8 +165,7 @@
return null;
}
FastField method = new FastField(type, name);
- Method result = (Method)cache.get(method);
-
+ Method result = (Method)declaredCache.get(method);
if (result == null) {
try {
result = type.getDeclaredMethod(name, parameterTypes);
@@ -168,12 +175,33 @@
} catch (NoSuchMethodException e) {
result = getMethod(type.getSuperclass(), name, parameterTypes);
}
- cache.put(method, result);
+ declaredCache.put(method, result);
}
return result;
}
+ private Method getRRMethod(final Class type, final String name) {
+ final FastField method = new FastField(type, name);
+ Method result = (Method)resRepCache.get(method);
+ if (result == null) {
+ result = getMethod(type, name, EMPTY_CLASSES, true);
+ if (result != null && result.getDeclaringClass() != type) {
+ if ((result.getModifiers() & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0) {
+ if ((result.getModifiers() & Modifier.PRIVATE) > 0
+ || type.getPackage() != result.getDeclaringClass().getPackage()) {
+ result = NO_METHOD;
+ }
+ }
+ } else if (result == null) {
+ result = NO_METHOD;
+ }
+ resRepCache.put(method, result);
+ }
+ return result == NO_METHOD ? null : result;
+ }
+
public void flushCache() {
- cache.keySet().retainAll(Arrays.asList(OBJECT_TYPE_FIELDS));
+ declaredCache.keySet().retainAll(Arrays.asList(OBJECT_TYPE_FIELDS));
+ resRepCache.keySet().retainAll(Arrays.asList(OBJECT_TYPE_FIELDS));
}
}
Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/mapper/AbstractAttributeAliasingMapper.java (2301 => 2302)
--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/mapper/AbstractAttributeAliasingMapper.java 2014-10-30 12:58:59 UTC (rev 2301)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/mapper/AbstractAttributeAliasingMapper.java 2014-10-30 13:18:10 UTC (rev 2302)
@@ -34,7 +34,7 @@
nameToAlias.put(attributeName, alias);
}
- private Object readResolve() {
+ Object readResolve() {
nameToAlias = new HashMap();
for (final Iterator iter = aliasToName.keySet().iterator(); iter.hasNext();) {
final Object alias = iter.next();
Modified: branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/AbstractReferenceTest.java (2301 => 2302)
--- branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/AbstractReferenceTest.java 2014-10-30 12:58:59 UTC (rev 2301)
+++ branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/AbstractReferenceTest.java 2014-10-30 13:18:10 UTC (rev 2302)
@@ -397,7 +397,7 @@
return true;
}
- private Object writeReplace() {
+ protected Object writeReplace() {
if (getClass() == TreeData.class) {
return this;
}
Modified: branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/SerializationCallbackOrderTest.java (2301 => 2302)
--- branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/SerializationCallbackOrderTest.java 2014-10-30 12:58:59 UTC (rev 2301)
+++ branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/SerializationCallbackOrderTest.java 2014-10-30 13:18:10 UTC (rev 2302)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2005 Joe Walnes.
- * Copyright (C) 2006, 2007 XStream Committers.
+ * Copyright (C) 2006, 2007, 2014 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -32,58 +32,203 @@
}
- // --- Sample class hiearchy
+ // --- Sample class hierarchy
- public static class Base implements Serializable{
+ public static class PrivateBase implements Serializable{
private void writeObject(ObjectOutputStream out) throws IOException {
- log.actual("Base.writeObject() start");
+ log.actual("PrivateBase.writeObject() start");
out.defaultWriteObject();
- log.actual("Base.writeObject() end");
+ log.actual("PrivateBase.writeObject() end");
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
- log.actual("Base.readObject() start");
+ log.actual("PrivateBase.readObject() start");
in.defaultReadObject();
- log.actual("Base.readObject() end");
+ log.actual("PrivateBase.readObject() end");
}
private Object writeReplace() {
- log.actual("Base.writeReplace()");
+ log.actual("PrivateBase.writeReplace()");
return this;
}
private Object readResolve() {
- log.actual("Base.readResolve()");
+ log.actual("PrivateBase.readResolve()");
return this;
}
}
- public static class Child extends Base implements Serializable{
+ public static class PrivateChildOwnRR extends PrivateBase implements Serializable{
private void writeObject(ObjectOutputStream out) throws IOException {
- log.actual("Child.writeObject() start");
+ log.actual("PrivateChildOwnRR.writeObject() start");
out.defaultWriteObject();
- log.actual("Child.writeObject() end");
+ log.actual("PrivateChildOwnRR.writeObject() end");
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
- log.actual("Child.readObject() start");
+ log.actual("PrivateChildOwnRR.readObject() start");
in.defaultReadObject();
- log.actual("Child.readObject() end");
+ log.actual("PrivateChildOwnRR.readObject() end");
}
private Object writeReplace() {
- log.actual("Child.writeReplace()");
+ log.actual("PrivateChildOwnRR.writeReplace()");
return this;
}
private Object readResolve() {
- log.actual("Child.readResolve()");
+ log.actual("PrivateChildOwnRR.readResolve()");
return this;
}
}
+ public static class PrivateChildNoRR extends PrivateBase implements Serializable{
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ log.actual("PrivateChildNoRR.writeObject() start");
+ out.defaultWriteObject();
+ log.actual("PrivateChildNoRR.writeObject() end");
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ log.actual("PrivateChildNoRR.readObject() start");
+ in.defaultReadObject();
+ log.actual("PrivateChildNoRR.readObject() end");
+ }
+ }
+
+ public static class ProtectedBase implements Serializable{
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ log.actual("ProtectedBase.writeObject() start");
+ out.defaultWriteObject();
+ log.actual("ProtectedBase.writeObject() end");
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ log.actual("ProtectedBase.readObject() start");
+ in.defaultReadObject();
+ log.actual("ProtectedBase.readObject() end");
+ }
+
+ protected Object writeReplace() {
+ log.actual("ProtectedBase.writeReplace()");
+ return this;
+ }
+
+ protected Object readResolve() {
+ log.actual("ProtectedBase.readResolve()");
+ return this;
+ }
+ }
+
+ public static class ProtectedChildOwnRR extends ProtectedBase implements Serializable{
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ log.actual("ProtectedChildOwnRR.writeObject() start");
+ out.defaultWriteObject();
+ log.actual("ProtectedChildOwnRR.writeObject() end");
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ log.actual("ProtectedChildOwnRR.readObject() start");
+ in.defaultReadObject();
+ log.actual("ProtectedChildOwnRR.readObject() end");
+ }
+
+ protected Object writeReplace() {
+ log.actual("ProtectedChildOwnRR.writeReplace()");
+ return this;
+ }
+
+ protected Object readResolve() {
+ log.actual("ProtectedChildOwnRR.readResolve()");
+ return this;
+ }
+ }
+
+ public static class ProtectedChildInheritedRR extends ProtectedBase implements Serializable{
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ log.actual("ProtectedChildInheritedRR.writeObject() start");
+ out.defaultWriteObject();
+ log.actual("ProtectedChildInheritedRR.writeObject() end");
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ log.actual("ProtectedChildInheritedRR.readObject() start");
+ in.defaultReadObject();
+ log.actual("ProtectedChildInheritedRR.readObject() end");
+ }
+ }
+
+ public static class PackageBase implements Serializable{
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ log.actual("PackageBase.writeObject() start");
+ out.defaultWriteObject();
+ log.actual("PackageBase.writeObject() end");
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ log.actual("PackageBase.readObject() start");
+ in.defaultReadObject();
+ log.actual("PackageBase.readObject() end");
+ }
+
+ Object writeReplace() {
+ log.actual("PackageBase.writeReplace()");
+ return this;
+ }
+
+ Object readResolve() {
+ log.actual("PackageBase.readResolve()");
+ return this;
+ }
+ }
+
+ public static class PackageChildOwnRR extends PackageBase implements Serializable{
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ log.actual("PackageChildOwnRR.writeObject() start");
+ out.defaultWriteObject();
+ log.actual("PackageChildOwnRR.writeObject() end");
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ log.actual("PackageChildOwnRR.readObject() start");
+ in.defaultReadObject();
+ log.actual("PackageChildOwnRR.readObject() end");
+ }
+
+ Object writeReplace() {
+ log.actual("PackageChildOwnRR.writeReplace()");
+ return this;
+ }
+
+ Object readResolve() {
+ log.actual("PackageChildOwnRR.readResolve()");
+ return this;
+ }
+ }
+
+ public static class PackageChildInheritedRR extends PackageBase implements Serializable{
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ log.actual("PackageChildInheritedRR.writeObject() start");
+ out.defaultWriteObject();
+ log.actual("PackageChildInheritedRR.writeObject() end");
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ log.actual("PackageChildInheritedRR.readObject() start");
+ in.defaultReadObject();
+ log.actual("PackageChildInheritedRR.readObject() end");
+ }
+ }
+
// --- Convenience wrappers around Java Object Serialization
private byte[] javaSerialize(Object object) throws IOException {
@@ -101,47 +246,195 @@
// --- Tests
- public void testJavaSerialization() throws IOException {
+ public void testJavaSerializationOwnPrivateRR() throws IOException {
// expectations
- log.expect("Child.writeReplace()");
- log.expect("Base.writeObject() start");
- log.expect("Base.writeObject() end");
- log.expect("Child.writeObject() start");
- log.expect("Child.writeObject() end");
+ log.expect("PrivateChildOwnRR.writeReplace()");
+ log.expect("PrivateBase.writeObject() start");
+ log.expect("PrivateBase.writeObject() end");
+ log.expect("PrivateChildOwnRR.writeObject() start");
+ log.expect("PrivateChildOwnRR.writeObject() end");
// execute
- javaSerialize(new Child());
+ javaSerialize(new PrivateChildOwnRR());
// verify
log.verify();
}
- public void testXStreamSerialization() {
+ public void testJavaSerializationNoRR() throws IOException {
// expectations
- log.expect("Child.writeReplace()");
- log.expect("Base.writeObject() start");
- log.expect("Base.writeObject() end");
- log.expect("Child.writeObject() start");
- log.expect("Child.writeObject() end");
+ log.expect("PrivateBase.writeObject() start");
+ log.expect("PrivateBase.writeObject() end");
+ log.expect("PrivateChildNoRR.writeObject() start");
+ log.expect("PrivateChildNoRR.writeObject() end");
// execute
- xstream.toXML(new Child());
+ javaSerialize(new PrivateChildNoRR());
// verify
log.verify();
}
- public void testJavaDeserialization() throws IOException, ClassNotFoundException {
+ public void testJavaSerializationOwnProtectedRR() throws IOException {
+ // expectations
+ log.expect("ProtectedChildOwnRR.writeReplace()");
+ log.expect("ProtectedBase.writeObject() start");
+ log.expect("ProtectedBase.writeObject() end");
+ log.expect("ProtectedChildOwnRR.writeObject() start");
+ log.expect("ProtectedChildOwnRR.writeObject() end");
+
+ // execute
+ javaSerialize(new ProtectedChildOwnRR());
+
+ // verify
+ log.verify();
+ }
+
+ public void testJavaSerializationInheritedRR() throws IOException {
+ // expectations
+ log.expect("ProtectedBase.writeReplace()");
+ log.expect("ProtectedBase.writeObject() start");
+ log.expect("ProtectedBase.writeObject() end");
+ log.expect("ProtectedChildInheritedRR.writeObject() start");
+ log.expect("ProtectedChildInheritedRR.writeObject() end");
+
+ // execute
+ javaSerialize(new ProtectedChildInheritedRR());
+
+ // verify
+ log.verify();
+ }
+
+ public void testJavaSerializationOwnPackageRR() throws IOException {
+ // expectations
+ log.expect("PackageChildOwnRR.writeReplace()");
+ log.expect("PackageBase.writeObject() start");
+ log.expect("PackageBase.writeObject() end");
+ log.expect("PackageChildOwnRR.writeObject() start");
+ log.expect("PackageChildOwnRR.writeObject() end");
+
+ // execute
+ javaSerialize(new PackageChildOwnRR());
+
+ // verify
+ log.verify();
+ }
+
+ public void testJavaSerializationInheritedPackageRR() throws IOException {
+ // expectations
+ log.expect("PackageBase.writeReplace()");
+ log.expect("PackageBase.writeObject() start");
+ log.expect("PackageBase.writeObject() end");
+ log.expect("PackageChildInheritedRR.writeObject() start");
+ log.expect("PackageChildInheritedRR.writeObject() end");
+
+ // execute
+ javaSerialize(new PackageChildInheritedRR());
+
+ // verify
+ log.verify();
+ }
+
+ public void testXStreamSerializationOwnPrivateRR() {
+ // expectations
+ log.expect("PrivateChildOwnRR.writeReplace()");
+ log.expect("PrivateBase.writeObject() start");
+ log.expect("PrivateBase.writeObject() end");
+ log.expect("PrivateChildOwnRR.writeObject() start");
+ log.expect("PrivateChildOwnRR.writeObject() end");
+
+ // execute
+ xstream.toXML(new PrivateChildOwnRR());
+
+ // verify
+ log.verify();
+ }
+
+ public void testXStreamSerializationNoRR() {
+ // expectations
+ log.expect("PrivateBase.writeObject() start");
+ log.expect("PrivateBase.writeObject() end");
+ log.expect("PrivateChildNoRR.writeObject() start");
+ log.expect("PrivateChildNoRR.writeObject() end");
+
+ // execute
+ xstream.toXML(new PrivateChildNoRR());
+
+ // verify
+ log.verify();
+ }
+
+ public void testXStreamSerializationOwnProtectedRR() {
+ // expectations
+ log.expect("ProtectedChildOwnRR.writeReplace()");
+ log.expect("ProtectedBase.writeObject() start");
+ log.expect("ProtectedBase.writeObject() end");
+ log.expect("ProtectedChildOwnRR.writeObject() start");
+ log.expect("ProtectedChildOwnRR.writeObject() end");
+
+ // execute
+ xstream.toXML(new ProtectedChildOwnRR());
+
+ // verify
+ log.verify();
+ }
+
+ public void testXStreamSerializationOwnInheritedRR() {
+ // expectations
+ log.expect("ProtectedBase.writeReplace()");
+ log.expect("ProtectedBase.writeObject() start");
+ log.expect("ProtectedBase.writeObject() end");
+ log.expect("ProtectedChildInheritedRR.writeObject() start");
+ log.expect("ProtectedChildInheritedRR.writeObject() end");
+
+ // execute
+ xstream.toXML(new ProtectedChildInheritedRR());
+
+ // verify
+ log.verify();
+ }
+
+ public void testXStreamSerializationOwnPackageRR() {
+ // expectations
+ log.expect("PackageChildOwnRR.writeReplace()");
+ log.expect("PackageBase.writeObject() start");
+ log.expect("PackageBase.writeObject() end");
+ log.expect("PackageChildOwnRR.writeObject() start");
+ log.expect("PackageChildOwnRR.writeObject() end");
+
+ // execute
+ xstream.toXML(new PackageChildOwnRR());
+
+ // verify
+ log.verify();
+ }
+
+ public void testXStreamSerializationOwnInheritedPackageRR() {
+ // expectations
+ log.expect("PackageBase.writeReplace()");
+ log.expect("PackageBase.writeObject() start");
+ log.expect("PackageBase.writeObject() end");
+ log.expect("PackageChildInheritedRR.writeObject() start");
+ log.expect("PackageChildInheritedRR.writeObject() end");
+
+ // execute
+ xstream.toXML(new PackageChildInheritedRR());
+
+ // verify
+ log.verify();
+ }
+
+ public void testJavaDeserializationOwnPrivateRR() throws IOException, ClassNotFoundException {
// setup
- byte[] data = "" Child());
+ byte[] data = "" PrivateChildOwnRR());
log.reset();
// expectations
- log.expect("Base.readObject() start");
- log.expect("Base.readObject() end");
- log.expect("Child.readObject() start");
- log.expect("Child.readObject() end");
- log.expect("Child.readResolve()");
+ log.expect("PrivateBase.readObject() start");
+ log.expect("PrivateBase.readObject() end");
+ log.expect("PrivateChildOwnRR.readObject() start");
+ log.expect("PrivateChildOwnRR.readObject() end");
+ log.expect("PrivateChildOwnRR.readResolve()");
// execute
javaDeserialize(data);
@@ -150,26 +443,213 @@
log.verify();
}
- public void testXStreamDeserialization() {
+ public void testJavaDeserializationNoRR() throws IOException, ClassNotFoundException {
// setup
- String data = "" Child());
+ byte[] data = "" PrivateChildNoRR());
log.reset();
// expectations
- log.expect("Base.readObject() start");
- log.expect("Base.readObject() end");
- log.expect("Child.readObject() start");
- log.expect("Child.readObject() end");
- log.expect("Child.readResolve()");
+ log.expect("PrivateBase.readObject() start");
+ log.expect("PrivateBase.readObject() end");
+ log.expect("PrivateChildNoRR.readObject() start");
+ log.expect("PrivateChildNoRR.readObject() end");
// execute
+ javaDeserialize(data);
+
+ // verify
+ log.verify();
+ }
+
+ public void testJavaDeserializationOwnProtectedRR() throws IOException, ClassNotFoundException {
+ // setup
+ byte[] data = "" ProtectedChildOwnRR());
+ log.reset();
+
+ // expectations
+ log.expect("ProtectedBase.readObject() start");
+ log.expect("ProtectedBase.readObject() end");
+ log.expect("ProtectedChildOwnRR.readObject() start");
+ log.expect("ProtectedChildOwnRR.readObject() end");
+ log.expect("ProtectedChildOwnRR.readResolve()");
+
+ // execute
+ javaDeserialize(data);
+
+ // verify
+ log.verify();
+ }
+
+ public void testJavaDeserializationInheritedRR() throws IOException, ClassNotFoundException {
+ // setup
+ byte[] data = "" ProtectedChildInheritedRR());
+ log.reset();
+
+ // expectations
+ log.expect("ProtectedBase.readObject() start");
+ log.expect("ProtectedBase.readObject() end");
+ log.expect("ProtectedChildInheritedRR.readObject() start");
+ log.expect("ProtectedChildInheritedRR.readObject() end");
+ log.expect("ProtectedBase.readResolve()");
+
+ // execute
+ javaDeserialize(data);
+
+ // verify
+ log.verify();
+ }
+
+ public void testJavaDeserializationOwnPackageRR() throws IOException, ClassNotFoundException {
+ // setup
+ byte[] data = "" PackageChildOwnRR());
+ log.reset();
+
+ // expectations
+ log.expect("PackageBase.readObject() start");
+ log.expect("PackageBase.readObject() end");
+ log.expect("PackageChildOwnRR.readObject() start");
+ log.expect("PackageChildOwnRR.readObject() end");
+ log.expect("PackageChildOwnRR.readResolve()");
+
+ // execute
+ javaDeserialize(data);
+
+ // verify
+ log.verify();
+ }
+
+ public void testJavaDeserializationInheritedPackageRR() throws IOException, ClassNotFoundException {
+ // setup
+ byte[] data = "" PackageChildInheritedRR());
+ log.reset();
+
+ // expectations
+ log.expect("PackageBase.readObject() start");
+ log.expect("PackageBase.readObject() end");
+ log.expect("PackageChildInheritedRR.readObject() start");
+ log.expect("PackageChildInheritedRR.readObject() end");
+ log.expect("PackageBase.readResolve()");
+
+ // execute
+ javaDeserialize(data);
+
+ // verify
+ log.verify();
+ }
+
+ public void testXStreamDeserializationOwnPrivateRR() {
+ // setup
+ String data = "" PrivateChildOwnRR());
+ log.reset();
+
+ // expectations
+ log.expect("PrivateBase.readObject() start");
+ log.expect("PrivateBase.readObject() end");
+ log.expect("PrivateChildOwnRR.readObject() start");
+ log.expect("PrivateChildOwnRR.readObject() end");
+ log.expect("PrivateChildOwnRR.readResolve()");
+
+ // execute
xstream.fromXML(data);
// verify
log.verify();
}
+ public void testXStreamDeserializationNoRR() {
+ // setup
+ String data = "" PrivateChildNoRR());
+ log.reset();
+ // expectations
+ log.expect("PrivateBase.readObject() start");
+ log.expect("PrivateBase.readObject() end");
+ log.expect("PrivateChildNoRR.readObject() start");
+ log.expect("PrivateChildNoRR.readObject() end");
+
+ // execute
+ xstream.fromXML(data);
+
+ // verify
+ log.verify();
+ }
+
+ public void testXStreamDeserializationOwnProtectedRR() {
+ // setup
+ String data = "" ProtectedChildOwnRR());
+ log.reset();
+
+ // expectations
+ log.expect("ProtectedBase.readObject() start");
+ log.expect("ProtectedBase.readObject() end");
+ log.expect("ProtectedChildOwnRR.readObject() start");
+ log.expect("ProtectedChildOwnRR.readObject() end");
+ log.expect("ProtectedChildOwnRR.readResolve()");
+
+ // execute
+ xstream.fromXML(data);
+
+ // verify
+ log.verify();
+ }
+
+ public void testXStreamDeserializationInheritedRR() {
+ // setup
+ String data = "" ProtectedChildInheritedRR());
+ log.reset();
+
+ // expectations
+ log.expect("ProtectedBase.readObject() start");
+ log.expect("ProtectedBase.readObject() end");
+ log.expect("ProtectedChildInheritedRR.readObject() start");
+ log.expect("ProtectedChildInheritedRR.readObject() end");
+ log.expect("ProtectedBase.readResolve()");
+
+ // execute
+ xstream.fromXML(data);
+
+ // verify
+ log.verify();
+ }
+
+ public void testXStreamDeserializationOwnPackageRR() {
+ // setup
+ String data = "" PackageChildOwnRR());
+ log.reset();
+
+ // expectations
+ log.expect("PackageBase.readObject() start");
+ log.expect("PackageBase.readObject() end");
+ log.expect("PackageChildOwnRR.readObject() start");
+ log.expect("PackageChildOwnRR.readObject() end");
+ log.expect("PackageChildOwnRR.readResolve()");
+
+ // execute
+ xstream.fromXML(data);
+
+ // verify
+ log.verify();
+ }
+
+ public void testXStreamDeserializationInheritedPackageRR() {
+ // setup
+ String data = "" PackageChildInheritedRR());
+ log.reset();
+
+ // expectations
+ log.expect("PackageBase.readObject() start");
+ log.expect("PackageBase.readObject() end");
+ log.expect("PackageChildInheritedRR.readObject() start");
+ log.expect("PackageChildInheritedRR.readObject() end");
+ log.expect("PackageBase.readResolve()");
+
+ // execute
+ xstream.fromXML(data);
+
+ // verify
+ log.verify();
+ }
+
public static class ParentNotTransient implements Serializable {
public int somethingNotTransient;
Modified: branches/v-1.4.x/xstream-distribution/src/content/changes.html (2301 => 2302)
--- branches/v-1.4.x/xstream-distribution/src/content/changes.html 2014-10-30 12:58:59 UTC (rev 2301)
+++ branches/v-1.4.x/xstream-distribution/src/content/changes.html 2014-10-30 13:18:10 UTC (rev 2302)
@@ -35,6 +35,7 @@
<h2>Minor changes</h2>
<ul>
+ <li>XSTR-762: Private method readResolve() called on base classes.</li>
<li>XSTR-755: ExternalizableConverter does not respect writeReplace and readResolve.</li>
<li>XSTR-757: Deserialized TreeSet does not honor remove(Object) return value contract.</li>
<li>Fix: DateConverter ignores provided locale.</li>
@@ -46,6 +47,8 @@
<h2>API changes</h2>
<ul>
+ <li>c.t.x.converters.reflection.AbstractReflectionConverter.readResolve() is protected now.</li>
+ <li>c.t.x.mapper.AbstractAttributeAliasingMapper.readResolve() is protected now.</li>
<li>Deprecated c.t.x.converters.extended.StackTraceElementFactory, it is an internal helper class.</li>
<li>Deprecated c.t.x.io.AttributeNameIterator, it is an internal helper class.</li>
<li>Deprecated c.t.x.XStream.useXStream11XmlFriendlyMapper(), corresponding
To unsubscribe from this list please visit:
