CORDA-1229 - Setter serialization fails with lists

Looks like the super / sub type inference of setter param vs
getter param is the wrong way around. Also, Setter Type should
be the generic type, not just the type

the property must be a supertype of the setter parameter

the getter must be a supertype of the setter parameter
This commit is contained in:
Katelyn Baker 2018-04-11 18:32:23 +01:00 committed by Kat Baker
parent 72bd530b11
commit f19bcea82f
4 changed files with 41 additions and 4 deletions

View File

@ -7,6 +7,9 @@ release, see :doc:`upgrade-notes`.
Unreleased Unreleased
========== ==========
* Fix CORDA-1229. Setter based serialization was broken with generic types when the property was stored
as the interface type, List for example.
* java.security.cert.CRLReason added to the default Whitelist. * java.security.cert.CRLReason added to the default Whitelist.
* java.security.cert.X509CRL serialization support added. * java.security.cert.X509CRL serialization support added.

View File

@ -305,7 +305,8 @@ fun propertiesForSerializationFromSetters(
"takes too many arguments") "takes too many arguments")
} }
val setterType = setter.parameterTypes[0]!! //val setterType = setter.parameterTypes[0]!!
val setterType = setter.genericParameterTypes[0]!!
if ((property.value.field != null) && if ((property.value.field != null) &&
(!(TypeToken.of(property.value.field?.genericType!!).isSupertypeOf(setterType)))) { (!(TypeToken.of(property.value.field?.genericType!!).isSupertypeOf(setterType)))) {
@ -315,10 +316,10 @@ fun propertiesForSerializationFromSetters(
} }
// make sure the setter returns the same type (within inheritance bounds) the getter accepts // make sure the setter returns the same type (within inheritance bounds) the getter accepts
if (!(TypeToken.of (setterType).isSupertypeOf(getter.returnType))) { if (!(TypeToken.of (getter.genericReturnType).isSupertypeOf(setterType))) {
throw NotSerializableException("Defined setter for parameter ${property.value.field?.name} " + throw NotSerializableException("Defined setter for parameter ${property.value.field?.name} " +
"takes parameter of type $setterType yet the defined getter returns a value of type " + "takes parameter of type $setterType yet the defined getter returns a value of type " +
"${getter.returnType}") "${getter.returnType} [${getter.genericReturnType}]")
} }
this += PropertyAccessorGetterSetter( this += PropertyAccessorGetterSetter(
idx++, idx++,

View File

@ -7,6 +7,8 @@ import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.io.NotSerializableException; import java.io.NotSerializableException;
import java.util.ArrayList;
import java.util.List;
public class SetterConstructorTests { public class SetterConstructorTests {
@ -64,6 +66,13 @@ public class SetterConstructorTests {
public void setC(int c) { this.c = c; } public void setC(int c) { this.c = c; }
} }
static class CIntList {
private List<Integer> l;
public List getL() { return l; }
public void setL(List<Integer> l) { this.l = l; }
}
static class Inner1 { static class Inner1 {
private String a; private String a;
@ -315,4 +324,29 @@ public class SetterConstructorTests {
Assertions.assertThatThrownBy(() -> new SerializationOutput(factory1).serialize(tm)).isInstanceOf( Assertions.assertThatThrownBy(() -> new SerializationOutput(factory1).serialize(tm)).isInstanceOf(
NotSerializableException.class); NotSerializableException.class);
} }
// This not blowing up means it's working
@Test
public void intList() throws NotSerializableException {
CIntList cil = new CIntList();
List<Integer> l = new ArrayList<>();
l.add(1);
l.add(2);
l.add(3);
cil.setL(l);
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
SerializerFactory factory1 = new SerializerFactory(
AllWhitelist.INSTANCE,
ClassLoader.getSystemClassLoader(),
evolutionSerialiserGetter,
fingerPrinter);
// if we've got super / sub types on the setter vs the unerlaying type the wrong way around this will
// explode
new SerializationOutput(factory1).serialize(cil);
}
} }

View File

@ -1310,6 +1310,5 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
C(12).serializeE() C(12).serializeE()
}.withMessageContaining("has synthetic fields and is likely a nested inner class") }.withMessageContaining("has synthetic fields and is likely a nested inner class")
} }
} }