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
|
||||
rmi.idToIface[id] = clazz
|
||||
rmi.ifaceToId[clazz] = id
|
||||
// ALL REGISTRATIONS MUST BE IMPL! (only RMI can have IFACE)
|
||||
rmi.idToImpl[id] = clazz
|
||||
rmi.implToId[clazz] = id
|
||||
}
|
||||
|
||||
open fun register(kryo: KryoExtra) {}
|
||||
|
@ -106,16 +106,77 @@ internal class ClassRegistrationForRmi(ifaceClass: Class<*>,
|
||||
override fun register(kryo: KryoExtra, rmi: RmiHolder) {
|
||||
// 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) {
|
||||
// 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!
|
||||
|
||||
val registration = kryo.classResolver.getRegistration(clazz)
|
||||
@ -129,13 +190,11 @@ internal class ClassRegistrationForRmi(ifaceClass: Class<*>,
|
||||
// just register the iface class
|
||||
id = kryo.register(clazz, serializer).id
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// RMI-SERVER
|
||||
|
||||
|
||||
if (implClass != null) {
|
||||
// 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) {
|
||||
id = registration.id
|
||||
|
||||
@ -147,8 +206,7 @@ internal class ClassRegistrationForRmi(ifaceClass: Class<*>,
|
||||
id = kryo.register(implClass, serializer).id
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// have to get the ID for the interface (if it exists)
|
||||
info = if (implClass == null) {
|
||||
|
@ -333,7 +333,8 @@ open class Serialization(private val references: Boolean = true, private val fac
|
||||
classesToRegister.add(ClassRegistration3(it))
|
||||
}
|
||||
|
||||
initializeClassRegistrations()
|
||||
val kryo = initKryo() // this will initialize the class registrations
|
||||
initializeClassRegistrations(kryo)
|
||||
} else {
|
||||
if (!initialized.compareAndSet(expect = false, update = true)) {
|
||||
// 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 {
|
||||
val kryo = initKryo()
|
||||
|
||||
private fun initializeClassRegistrations(kryo: KryoExtra): Boolean {
|
||||
// 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!
|
||||
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>
|
||||
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!
|
||||
initKryo()
|
||||
kryo = initKryo()
|
||||
|
||||
// now do a round-trip through the class registrations
|
||||
return initializeClassRegistrations()
|
||||
return initializeClassRegistrations(kryo)
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user