Skip to content

Incompatible With Kotlin Coroutines #525

@bcwhite-code

Description

@bcwhite-code

Objectify stores its context as a thread-local variable. However, Kotlin's "coroutines" can jump threads as necessary when a "suspend" function waits for something. Whatever context was created for the original thread is then inaccessible, leading to failures.

The following KTOR 3.3.1 handler demonstrates this but it isn't specific to that system:

get("/test") {
    val id = 5853572849213031L
    val objectifyCloser = ObjectifyService.begin()
    var user = ObjectifyService.ofy().load().type(UserInfo::class.java).id(id).now()
    try {
        for (i in 1..1000000000) {
            kotlinx.coroutines.delay(1000)
            RWLog.d(LOGTAG) { "${user.accountId}: ${i}" }
            user = ObjectifyService.ofy().load().type(UserInfo::class.java).id(id).now()
        }
    } catch (e: Throwable) {
        RWLog.d(LOGTAG) { "${user.accountId}: ${e.toString()}" }
    }
    objectifyCloser.close()
}

Older KTOR libraries didn't jump threads and would run just fine, spitting out one log message per second. With 3.3.1, it fails immediately:

2025.11.04 21:45:20.271 Main: 5853572849213031: 1
2025.11.04 21:45:20.278 Main: 5853572849213031: java.lang.IllegalStateException: You have not started an Objectify context. You are missing a call to run() or you do not have the ObjectifyFilter installed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions