Trying upgrade from 0.7.1. to 0.8. Got "konan.work...
# kotlin-native
k
Trying upgrade from 0.7.1. to 0.8. Got "konan.worker.InvalidMutabilityException: mutation attempt of frozen" (https://github.com/JetBrains/kotlin-native/issues/1775) I have object GlobalServices , that have several lateinit fields, that initialized during app startup. What would be the right way to fix it? Kotlin code is used as library in Swift iOS project. Services that initialized inside kotlin, require some params, and depends on each other. Also having global object, allow to retrieve corresponding service directly from class.
k
Not exactly sure what you're asking, but will take a stab at it. "GlobalServices" is an object, which means in 0.8+ it'll be frozen by default. You can mark it @ThreadLocal, but you'll need to make sure you only access it from one thread (I assume main thread). Alternatively, rather than lateinit, use AtomicReference for the fields.
o
Kevin is correct, also
atomicLazy
(https://github.com/JetBrains/kotlin-native/blob/699d530e8727a86a4e3ade59fdb2a88e733c7b7d/runtime/src/main/kotlin/konan/worker/Atomics.kt#L198) could be helpful, if you are OK that init lambda is frozen
k
As I understood, suggested ways are kotlin-native speciffic. They will not work on jvm.
o
yes
k
so, how i could do it for jvm and ios with the same code?
What i want is to statically access objects (singletong services, with state), that were created in some init phase. These objects receive some initialisation data from outside of kotlin code.
o
guess it depends on the usecase, generally speaking “common objects” are immutable, so you could either split common object in such a way, that platform-specific mutable (lateinit) objects are referred from the immutable object, and are implemented on Native using AtomicReference
k
Ok, here some very similar example. My kotlin library need to have configuration, that is accessible in every part of my kotlin code. Configuration (e.g. as hashmap) is set from parent app (swift,jvm,etc). What would be way to pass configuration to every other class, without passing it through the whole tree? ClassA create ClassB, which create ClassC, which create ClassD. ClassD need to get some values from Configuration. A,B,C have nothing to do with configuration, and preferably should not be aware of it. I have 5 cases like configuration, and passing their references everywhere, or context with all of them, will look very ugly and hard to maintain.
But yes, if there no other easy way, I'm mentally ready to pass "context" object for every class constructor 🙂
But there should be better way, shouldn't it?
o
Do you really need them to be mutable?
k
no
but they have mutable state inside them
ios app crashes on runtime, if that immutable class modify some internal variable (value cache in my case).
o
it means, that you have a potential concurrency issue at this place, as this cache could be modified simultaniously
k
Can I do something, if i know that kotlin code will be always executed in same single thread?
o
mark it with @ThreadLocal annotation (and if you want MPP, create stub annotation for JVM with the same name for now)
k
thx