Removed DeserializeAsKotlinObjectDef interface as serialisation of Kotlin objects is now handled automatically

This commit is contained in:
Shams Asari 2017-07-06 15:06:04 +01:00
parent 2b3f6d9701
commit fc97fb2368
6 changed files with 14 additions and 37 deletions

View File

@ -2,7 +2,6 @@ package net.corda.core.contracts
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.DeserializeAsKotlinObjectDef
import net.corda.core.transactions.LedgerTransaction import net.corda.core.transactions.LedgerTransaction
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import java.security.PublicKey import java.security.PublicKey
@ -61,7 +60,7 @@ sealed class TransactionType {
abstract fun verifyTransaction(tx: LedgerTransaction) abstract fun verifyTransaction(tx: LedgerTransaction)
/** A general transaction type where transaction validity is determined by custom contract code */ /** A general transaction type where transaction validity is determined by custom contract code */
object General : TransactionType(), DeserializeAsKotlinObjectDef { object General : TransactionType() {
/** Just uses the default [TransactionBuilder] with no special logic */ /** Just uses the default [TransactionBuilder] with no special logic */
class Builder(notary: Party?) : TransactionBuilder(General, notary) class Builder(notary: Party?) : TransactionBuilder(General, notary)
@ -141,7 +140,7 @@ sealed class TransactionType {
* A special transaction type for reassigning a notary for a state. Validation does not involve running * A special transaction type for reassigning a notary for a state. Validation does not involve running
* any contract code, it just checks that the states are unmodified apart from the notary field. * any contract code, it just checks that the states are unmodified apart from the notary field.
*/ */
object NotaryChange : TransactionType(), DeserializeAsKotlinObjectDef { object NotaryChange : TransactionType() {
/** /**
* A transaction builder that automatically sets the transaction type to [NotaryChange] * A transaction builder that automatically sets the transaction type to [NotaryChange]
* and adds the list of participants to the signers set for every input state. * and adds the list of participants to the signers set for every input state.

View File

@ -86,9 +86,6 @@ object DefaultKryoCustomizer {
// This ensures a NonEmptySetSerializer is constructed with an initial value. // This ensures a NonEmptySetSerializer is constructed with an initial value.
register(NonEmptySet::class.java, NonEmptySetSerializer) register(NonEmptySet::class.java, NonEmptySetSerializer)
/** This ensures any kotlin objects that implement [DeserializeAsKotlinObjectDef] are read back in as singletons. */
addDefaultSerializer(DeserializeAsKotlinObjectDef::class.java, KotlinObjectSerializer)
addDefaultSerializer(SerializeAsToken::class.java, SerializeAsTokenSerializer<SerializeAsToken>()) addDefaultSerializer(SerializeAsToken::class.java, SerializeAsTokenSerializer<SerializeAsToken>())
register(MetaData::class.java, MetaDataSerializer) register(MetaData::class.java, MetaDataSerializer)

View File

@ -462,20 +462,6 @@ inline fun <reified T> readListOfLength(kryo: Kryo, input: Input, minLen: Int =
return list return list
} }
/** Marker interface for kotlin object definitions so that they are deserialized as the singleton instance. */
// TODO This is not needed anymore
interface DeserializeAsKotlinObjectDef
/** Serializer to deserialize kotlin object definitions marked with [DeserializeAsKotlinObjectDef]. */
object KotlinObjectSerializer : Serializer<DeserializeAsKotlinObjectDef>() {
override fun read(kryo: Kryo, input: Input, type: Class<DeserializeAsKotlinObjectDef>): DeserializeAsKotlinObjectDef {
// read the public static INSTANCE field that kotlin compiler generates.
return type.getField("INSTANCE").get(null) as DeserializeAsKotlinObjectDef
}
override fun write(kryo: Kryo, output: Output, obj: DeserializeAsKotlinObjectDef) {}
}
// No ClassResolver only constructor. MapReferenceResolver is the default as used by Kryo in other constructors. // No ClassResolver only constructor. MapReferenceResolver is the default as used by Kryo in other constructors.
private val internalKryoPool = KryoPool.Builder { DefaultKryoCustomizer.customize(CordaKryo(makeAllButBlacklistedClassResolver())) }.build() private val internalKryoPool = KryoPool.Builder { DefaultKryoCustomizer.customize(CordaKryo(makeAllButBlacklistedClassResolver())) }.build()
private val kryoPool = KryoPool.Builder { DefaultKryoCustomizer.customize(CordaKryo(makeStandardClassResolver())) }.build() private val kryoPool = KryoPool.Builder { DefaultKryoCustomizer.customize(CordaKryo(makeStandardClassResolver())) }.build()
@ -533,7 +519,7 @@ inline fun <T : Any> Kryo.register(
return register( return register(
type.java, type.java,
object : Serializer<T>() { object : Serializer<T>() {
override fun read(kryo: Kryo, input: Input, type: Class<T>): T = read(kryo, input) override fun read(kryo: Kryo, input: Input, clazz: Class<T>): T = read(kryo, input)
override fun write(kryo: Kryo, output: Output, obj: T) = write(kryo, output, obj) override fun write(kryo: Kryo, output: Output, obj: T) = write(kryo, output, obj)
} }
) )

View File

@ -3,10 +3,9 @@ package net.corda.core.serialization
import com.esotericsoftware.kryo.Kryo import com.esotericsoftware.kryo.Kryo
import com.google.common.primitives.Ints import com.google.common.primitives.Ints
import net.corda.core.crypto.* import net.corda.core.crypto.*
import net.corda.node.services.persistence.NodeAttachmentService
import net.corda.testing.ALICE import net.corda.testing.ALICE
import net.corda.testing.BOB import net.corda.testing.BOB
import net.corda.node.services.messaging.Ack
import net.corda.node.services.persistence.NodeAttachmentService
import net.corda.testing.BOB_PUBKEY import net.corda.testing.BOB_PUBKEY
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.assertThatThrownBy
@ -16,7 +15,8 @@ import org.junit.Test
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.InputStream import java.io.InputStream
import java.security.cert.* import java.security.cert.CertPath
import java.security.cert.CertificateFactory
import java.time.Instant import java.time.Instant
import java.util.* import java.util.*
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -92,11 +92,10 @@ class KryoTests {
} }
@Test @Test
fun `write and read Ack`() { fun `write and read Kotlin object singleton`() {
val tokenizableBefore = Ack val serialised = TestSingleton.serialize(kryo)
val serializedBytes = tokenizableBefore.serialize(kryo) val deserialised = serialised.deserialize(kryo)
val tokenizableAfter = serializedBytes.deserialize(kryo) assertThat(deserialised).isSameAs(TestSingleton)
assertThat(tokenizableAfter).isSameAs(tokenizableBefore)
} }
@Test @Test
@ -173,4 +172,7 @@ class KryoTests {
override fun toString(): String = "Cyclic($value)" override fun toString(): String = "Cyclic($value)"
} }
@CordaSerializable
private object TestSingleton
} }

View File

@ -8,7 +8,6 @@ import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.services.DEFAULT_SESSION_ID import net.corda.core.node.services.DEFAULT_SESSION_ID
import net.corda.core.node.services.PartyInfo import net.corda.core.node.services.PartyInfo
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.DeserializeAsKotlinObjectDef
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.asn1.x500.X500Name
@ -229,10 +228,3 @@ object TopicStringValidator {
/** @throws IllegalArgumentException if the given topic contains invalid characters */ /** @throws IllegalArgumentException if the given topic contains invalid characters */
fun check(tag: String) = require(regex.matcher(tag).matches()) fun check(tag: String) = require(regex.matcher(tag).matches())
} }
/**
* A general Ack message that conveys no content other than it's presence for use when you want an acknowledgement
* from a recipient. Using [Unit] can be ambiguous as it is similar to [Void] and so could mean no response.
*/
@CordaSerializable
object Ack : DeserializeAsKotlinObjectDef

View File

@ -89,6 +89,7 @@ class StateMachineManager(val serviceHub: ServiceHubInternal,
} }
}.build() }.build()
// TODO Move this into the blacklist and upgrade the blacklist to allow custom messages
private object AutoCloseableSerialisationDetector : Serializer<AutoCloseable>() { private object AutoCloseableSerialisationDetector : Serializer<AutoCloseable>() {
override fun write(kryo: Kryo, output: Output, closeable: AutoCloseable) { override fun write(kryo: Kryo, output: Output, closeable: AutoCloseable) {
val message = if (closeable is CloseableIterator<*>) { val message = if (closeable is CloseableIterator<*>) {