Hi all, I've been getting an interesting error whe...
# announcements
t
Hi all, I've been getting an interesting error when my app runs for an extended period of time:
Copy code
17:10:33.977 [main] ERROR bees.stream.MessageStream - [MessageStream.kt:42] || - Message deserialization failed.
kotlin.reflect.full.IllegalCallableAccessException: java.lang.IllegalAccessException: class kotlin.reflect.jvm.internal.calls.CallerImpl$Constructor cannot access a member of class bees.stream.MessageStream$SystemMessage with modifiers "public"
        at kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:224)
        at kotlin.reflect.jvm.internal.KCallableImpl.callDefaultMethod$kotlin_reflect_api(KCallableImpl.kt:152)
        at kotlin.reflect.jvm.internal.KCallableImpl.callBy(KCallableImpl.kt:110)
        at com.squareup.moshi.kotlin.reflect.KotlinJsonAdapter.fromJson(KotlinJsonAdapter.kt:104)
        at com.squareup.moshi.JsonAdapter$2.fromJson(JsonAdapter.java:137)
        at com.squareup.moshi.JsonAdapter.fromJson(JsonAdapter.java:41)
        at bees.stream.MessageStream.onMessages(MessageStream.kt:39)
        at bees.stream.kafka.KafkaConsumerProducerStream.start(KafkaProducerConsumerStream.kt:64)
        at bees.BeesKt.main(bees.kt:65)
Caused by: java.lang.IllegalAccessException: class kotlin.reflect.jvm.internal.calls.CallerImpl$Constructor cannot access a member of class bees.stream.MessageStream$SystemMessage with modifiers "public"
        at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:361)
        at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:591)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
        at kotlin.reflect.jvm.internal.calls.CallerImpl$Constructor.call(CallerImpl.kt:41)
        at kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:106)
        ... 8 common frames omitted
17:10:33.989 [main] DEBUG bees.stream.MessageStream - [MessageStream.kt:83] || - Completed message processing. Returning 0 responses.
I have a Moshi instance whose job it is to do this deserialization. The class it wants to create is:
private data class SystemMessage(val command: String, val sessionId: UUID, val commandId: UUID, val data: Any)
. This is private to the class within the module. This only happens when the app is running for longer periods, if I restart and try again it works fine. When I search "java cannot access a member of a class with modifiers public", I get results which indicate that the class cannot be instantiated since it's private to its enclosing class. However, this doesn't explain why it works for some time if I restart the app. I've tried with JVM 8 and JVM 11, same error on both. This was built with Kotlin 1.3.10, but I'm going to try 1.3.20 now. Any help would be greatly appreciated 🙂
r
I guess the error message is misleading and you access a private member (that's this issue: https://youtrack.jetbrains.com/issue/KT-18408)
t
It's attempting to access a public constructor in a private class, and curiously this only fails if the app is running for some time (> 5 hours)
i don't think it's running out of memory or anything, but I don't know enough about Kotlin or the JVM to diagnose further 😕
r
kotlin cannot access a constructor of a private class
regardless if the constructor is public or not
t
yes, that's exactly my suspicion. do you have any hunches as to why it works when the app freshly starts, but not after time?
r
Do you use lazy vals or similar and it does not get called when you start the app but only after some time due to some event?
It is also likely that Moshi lazily instantiates deserializers
t
We do not. To summarize our logic, we listen to messages from an Apache Kafka instance, and when one comes in its body is deserialized and then further logic is applied. It's this deserialization step that fails. If the program receives a message soon after starting (i have one running for about an hour and it still works ok), the deserialization step works fine. but after some time (overnight, so > 7h) it breaks
r
Are those messages all SystemMessages or do you usually receive a different kind? (I am only guessing)
t
they're all system messages. i'm testing with a dummy producer
Moshi also throws different errors if the data is malformed, missing, etc
r
Strange that it works sometimes, accessing a private class should always fail, any module-info.class in place?
d
Kotlin can access constructors of a private class? As long as the class is in the same scope
t
@robstoll i don't see any
r
I am out of ideas then, sorry
t
@Dico the
SystemMessage
class is privately nested in a larger class
thank you for your help regardless 🙂 it's nbd to make the class public, I'll see where that gets me
d
@Tasos Stamadianos Seeing a very similar exception when load testing http4k/Jackson service. Did you ever establish what was the problem?
Seems there's something very weird happening with private (static) inner data classes.
347 Views