Fixed issues when registering RMI via registerRmi in different orders (rmi-client/rmi-server out-of-order in different ways).
This commit is contained in:
parent
af36f9a4ff
commit
6a590764ff
@ -68,8 +68,9 @@ internal abstract class ClassRegistration(val clazz: Class<*>, val serializer: S
|
|||||||
}
|
}
|
||||||
|
|
||||||
// now, we want to save the relationship between classes and kryoId
|
// now, we want to save the relationship between classes and kryoId
|
||||||
rmi.idToIface[id] = clazz
|
// ALL REGISTRATIONS MUST BE IMPL! (only RMI can have IFACE)
|
||||||
rmi.ifaceToId[clazz] = id
|
rmi.idToImpl[id] = clazz
|
||||||
|
rmi.implToId[clazz] = id
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun register(kryo: KryoExtra) {}
|
open fun register(kryo: KryoExtra) {}
|
||||||
|
@ -106,16 +106,77 @@ internal class ClassRegistrationForRmi(ifaceClass: Class<*>,
|
|||||||
override fun register(kryo: KryoExtra, rmi: RmiHolder) {
|
override fun register(kryo: KryoExtra, rmi: RmiHolder) {
|
||||||
// we override this, because we ALWAYS will call our RMI registration!
|
// we override this, because we ALWAYS will call our RMI registration!
|
||||||
|
|
||||||
|
// EVERY time initKryo() is called, this will happen. We have to ensure that every call produces the same results
|
||||||
|
|
||||||
|
// SUPER IMPORTANT:
|
||||||
|
// if RMI-CLIENT is registered, an IFACE will be present
|
||||||
|
// if RMI-SERVER is registered, and IFACE+IMPL will be present
|
||||||
|
// Both IFACE+IMPL must be checked when deciding if something needs to be overloaded, but ONLY for registerRmi
|
||||||
|
|
||||||
|
// check to see if we have already registered this as RMI-CLIENT
|
||||||
|
val alreadyRegistered = rmi.ifaceToId[clazz] != null
|
||||||
|
|
||||||
|
if (alreadyRegistered) {
|
||||||
|
// if we are ALREADY registered, then we have to make sure that RMI-CLIENT doesn't override RMI-SERVER...
|
||||||
|
val previousId = rmi.ifaceToId[clazz]
|
||||||
|
if (rmi.idToImpl[previousId] != null) {
|
||||||
|
// the impl was registered, which means that ANOTHER registration registered as RMI-SERVER.
|
||||||
|
|
||||||
|
if (implClass == null) {
|
||||||
|
// we are RMI-CLIENT.
|
||||||
|
// remove this registration, because we ALREADY have RMI-SERVER registered, and changing it to RMI-CLIENT will break rmi.
|
||||||
|
info = "CONFLICTED $previousId -> (RMI) Ignored duplicate registration for ${clazz.name}"
|
||||||
|
|
||||||
|
// mark this for later, so we don't try to do something with it
|
||||||
|
id = IGNORE_REGISTRATION
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
// Who cares. we are RMI-SERVER, so redo the registration info.
|
||||||
|
// MAYBE there are duplicates, but we don't care because whatever is registered as RMI-SERVER is the authority
|
||||||
|
val registration = kryo.classResolver.getRegistration(clazz)
|
||||||
|
if (registration != null) {
|
||||||
|
id = registration.id
|
||||||
|
|
||||||
|
// override that registration
|
||||||
|
kryo.register(implClass, serializer, id)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// now register the impl class
|
||||||
|
id = kryo.register(implClass, serializer).id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we don't have an IMPL registered (this means, only RMI-CLIENT was registered
|
||||||
|
|
||||||
|
// if we are RMI-SERVER, then we register, if we are RMI-CLIENT, then we are a duplicate registration (and should be ignored)
|
||||||
|
if (implClass != null) {
|
||||||
|
// this means we are the RMI-SERVER
|
||||||
|
val registration = kryo.classResolver.getRegistration(clazz)
|
||||||
|
if (registration != null) {
|
||||||
|
id = registration.id
|
||||||
|
|
||||||
|
// override that registration
|
||||||
|
kryo.register(implClass, serializer, id)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// now register the impl class
|
||||||
|
id = kryo.register(implClass, serializer).id
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// duplicate. ignore!
|
||||||
|
// do nothing, because this is ALREADY registered for RMI
|
||||||
|
info = "CONFLICTED $previousId -> (RMI) Ignored duplicate registration for ${clazz.name}"
|
||||||
|
|
||||||
|
// mark this for later, so we don't try to do something with it
|
||||||
|
id = IGNORE_REGISTRATION
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// this means we were NOT already registered
|
||||||
|
|
||||||
if (implClass == null) {
|
if (implClass == null) {
|
||||||
// this means we are the RMI-CLIENT
|
// this means we are the RMI-CLIENT
|
||||||
|
|
||||||
// see if we have the IMPL registered? NOT LIKELY, but possible
|
|
||||||
val existingId = rmi.ifaceToId[clazz]
|
|
||||||
if (existingId != null) {
|
|
||||||
implClass = rmi.idToImpl[existingId]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (implClass == null) {
|
|
||||||
// then we just register the interface class!
|
// then we just register the interface class!
|
||||||
|
|
||||||
val registration = kryo.classResolver.getRegistration(clazz)
|
val registration = kryo.classResolver.getRegistration(clazz)
|
||||||
@ -129,13 +190,11 @@ internal class ClassRegistrationForRmi(ifaceClass: Class<*>,
|
|||||||
// just register the iface class
|
// just register the iface class
|
||||||
id = kryo.register(clazz, serializer).id
|
id = kryo.register(clazz, serializer).id
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
// RMI-SERVER
|
||||||
|
|
||||||
|
|
||||||
if (implClass != null) {
|
|
||||||
// this means we are the RMI-SERVER
|
// this means we are the RMI-SERVER
|
||||||
val registration = kryo.classResolver.getRegistration(implClass) // we cannot register iface classes!
|
val registration = kryo.classResolver.getRegistration(clazz)
|
||||||
if (registration != null) {
|
if (registration != null) {
|
||||||
id = registration.id
|
id = registration.id
|
||||||
|
|
||||||
@ -147,8 +206,7 @@ internal class ClassRegistrationForRmi(ifaceClass: Class<*>,
|
|||||||
id = kryo.register(implClass, serializer).id
|
id = kryo.register(implClass, serializer).id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// have to get the ID for the interface (if it exists)
|
// have to get the ID for the interface (if it exists)
|
||||||
info = if (implClass == null) {
|
info = if (implClass == null) {
|
||||||
|
@ -333,7 +333,8 @@ open class Serialization(private val references: Boolean = true, private val fac
|
|||||||
classesToRegister.add(ClassRegistration3(it))
|
classesToRegister.add(ClassRegistration3(it))
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeClassRegistrations()
|
val kryo = initKryo() // this will initialize the class registrations
|
||||||
|
initializeClassRegistrations(kryo)
|
||||||
} else {
|
} else {
|
||||||
if (!initialized.compareAndSet(expect = false, update = true)) {
|
if (!initialized.compareAndSet(expect = false, update = true)) {
|
||||||
// the client CAN initialize more than once, since initialization happens in the handshake now
|
// the client CAN initialize more than once, since initialization happens in the handshake now
|
||||||
@ -344,9 +345,7 @@ open class Serialization(private val references: Boolean = true, private val fac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializeClassRegistrations(): Boolean {
|
private fun initializeClassRegistrations(kryo: KryoExtra): Boolean {
|
||||||
val kryo = initKryo()
|
|
||||||
|
|
||||||
// now MERGE all of the registrations (since we can have registrations overwrite newer/specific registrations based on ID
|
// now MERGE all of the registrations (since we can have registrations overwrite newer/specific registrations based on ID
|
||||||
// in order to get the ID's, these have to be registered with a kryo instance!
|
// in order to get the ID's, these have to be registered with a kryo instance!
|
||||||
val mergedRegistrations = mutableListOf<ClassRegistration>()
|
val mergedRegistrations = mutableListOf<ClassRegistration>()
|
||||||
@ -474,6 +473,7 @@ open class Serialization(private val references: Boolean = true, private val fac
|
|||||||
val classesToRegisterForRmi = listOf(*classesToRegister.toTypedArray()) as List<ClassRegistrationForRmi>
|
val classesToRegisterForRmi = listOf(*classesToRegister.toTypedArray()) as List<ClassRegistrationForRmi>
|
||||||
classesToRegister.clear()
|
classesToRegister.clear()
|
||||||
|
|
||||||
|
// NOTE: to be clear, the "client" can ONLY registerRmi(IFACE, IMPL), to have extra info as the RMI-SERVER!!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -530,10 +530,10 @@ open class Serialization(private val references: Boolean = true, private val fac
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we have to re-init so the registrations are set!
|
// we have to re-init so the registrations are set!
|
||||||
initKryo()
|
kryo = initKryo()
|
||||||
|
|
||||||
// now do a round-trip through the class registrations
|
// now do a round-trip through the class registrations
|
||||||
return initializeClassRegistrations()
|
return initializeClassRegistrations(kryo)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user