mirror of
https://github.com/corda/corda.git
synced 2025-06-23 01:19:00 +00:00
CORDA-1662 - Corda Serialization Evolution breaksdown with Java classes (#3427)
Nullability logic was relying on annotations that Kotlin applies by default but is left to the developer in Javaland. Change this around so it works for both. In Kotlin, the property must be nullable, in Java, it can't be a primitive.
This commit is contained in:
@ -0,0 +1,100 @@
|
||||
package net.corda.serialization.internal.amqp;
|
||||
|
||||
import kotlin.Suppress;
|
||||
import net.corda.core.serialization.SerializedBytes;
|
||||
import net.corda.serialization.internal.amqp.testutils.AMQPTestUtilsKt;
|
||||
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import java.io.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
public class JavaEvolutionTests {
|
||||
@Rule
|
||||
public final ExpectedException exception = ExpectedException.none();
|
||||
|
||||
// Class as it was when it was serialized and written to disk. Uncomment
|
||||
// if the test referencing the object needs regenerating.
|
||||
/*
|
||||
static class N1 {
|
||||
private String word;
|
||||
public N1(String word) { this.word = word; }
|
||||
public String getWord() { return word; }
|
||||
}
|
||||
*/
|
||||
// Class as it exists now with the newly added element
|
||||
static class N1 {
|
||||
private String word;
|
||||
private Integer wibble;
|
||||
|
||||
public N1(String word, Integer wibble) {
|
||||
this.word = word;
|
||||
this.wibble = wibble;
|
||||
}
|
||||
public String getWord() { return word; }
|
||||
public Integer getWibble() { return wibble; }
|
||||
}
|
||||
|
||||
// Class as it was when it was serialized and written to disk. Uncomment
|
||||
// if the test referencing the object needs regenerating.
|
||||
/*
|
||||
static class N2 {
|
||||
private String word;
|
||||
public N2(String word) { this.word = word; }
|
||||
public String getWord() { return word; }
|
||||
}
|
||||
*/
|
||||
|
||||
// Class as it exists now with the newly added element
|
||||
@SuppressWarnings("unused")
|
||||
static class N2 {
|
||||
private String word;
|
||||
private float wibble;
|
||||
|
||||
public N2(String word, float wibble) {
|
||||
this.word = word;
|
||||
this.wibble = wibble;
|
||||
}
|
||||
public String getWord() { return word; }
|
||||
public float getWibble() { return wibble; }
|
||||
}
|
||||
|
||||
SerializerFactory factory = AMQPTestUtilsKt.testDefaultFactory();
|
||||
|
||||
@Test
|
||||
public void testN1AddsNullableInt() throws IOException {
|
||||
// Uncomment to regenerate the base state of the test
|
||||
/*
|
||||
N1 n = new N1("potato");
|
||||
AMQPTestUtilsKt.writeTestResource(this, new SerializationOutput(factory).serialize(
|
||||
n, TestSerializationContext.testSerializationContext));
|
||||
*/
|
||||
|
||||
N1 n2 = new DeserializationInput(factory).deserialize(
|
||||
new SerializedBytes<>(AMQPTestUtilsKt.readTestResource(this)),
|
||||
N1.class,
|
||||
TestSerializationContext.testSerializationContext);
|
||||
assertEquals(n2.getWord(), "potato");
|
||||
assertNull(n2.getWibble());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testN2AddsPrimitive() throws IOException {
|
||||
// Uncomment to regenerate the base state of the test
|
||||
/*
|
||||
N2 n = new N2("This is only a test");
|
||||
|
||||
AMQPTestUtilsKt.writeTestResource(this, new SerializationOutput(factory).serialize(
|
||||
n, TestSerializationContext.testSerializationContext));
|
||||
*/
|
||||
|
||||
exception.expect(NotSerializableException.class);
|
||||
new DeserializationInput(factory).deserialize(
|
||||
new SerializedBytes<>(AMQPTestUtilsKt.readTestResource(this)),
|
||||
N2.class,
|
||||
TestSerializationContext.testSerializationContext);
|
||||
}
|
||||
}
|
@ -98,7 +98,7 @@ class StaticInitialisationOfSerializedObjectTest {
|
||||
// Version of a serializer factory that will allow the class carpenter living on the
|
||||
// factory to have a different whitelist applied to it than the factory
|
||||
class TestSerializerFactory(wl1: ClassWhitelist, wl2: ClassWhitelist) :
|
||||
SerializerFactory(wl1, ClassCarpenterImpl(ClassLoader.getSystemClassLoader(), wl2))
|
||||
SerializerFactory(wl1, ClassCarpenterImpl(wl2, ClassLoader.getSystemClassLoader()))
|
||||
|
||||
// This time have the serialization factory and the carpenter use different whitelists
|
||||
@Test
|
||||
|
@ -89,7 +89,7 @@ class CarpenterExceptionTests {
|
||||
// carpent that class up. However, when looking at the fields specified as properties of that class
|
||||
// we set the class loader of the ClassCarpenter to reject one of them, resulting in a CarpentryError
|
||||
// which we then want the code to wrap in a NotSerializeableException
|
||||
val cc = ClassCarpenterImpl(TestClassLoader(listOf(C2::class.jvmName)), AllWhitelist)
|
||||
val cc = ClassCarpenterImpl(AllWhitelist, TestClassLoader(listOf(C2::class.jvmName)))
|
||||
val factory = TestFactory(cc)
|
||||
|
||||
Assertions.assertThatThrownBy {
|
||||
|
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user