Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Kotlin function name being mangled when passing Duration

Tags:

kotlin

In my current Android application im investigating the use of Duration with coroutine delay function as follows:-

class WorkerTwo(private val context: Context, private val params: WorkerParameters) : CoroutineWorker(context, params) {

    @ExperimentalTime
    override suspend fun doWork(): Result = coroutineScope {
        (0..100 step 30).forEach {
            setProgress(workDataOf(PROGRESS to it))

            delay(Duration.Companion.seconds(1L)) // CRASH HERE!!!!!!!!!!!!
        }

        Result.success()
    }
}

However when I install and run my application it crashes as follows

 Caused by: java.lang.NoSuchMethodError: No static method delay-p9JZ4hM(JLkotlin/coroutines/Continuation;)Ljava/lang/Object; in class Lkotlinx/coroutines/DelayKt; or its super classes (declaration of 'kotlinx.coroutines.DelayKt' appears in /data/app/org.research.development.versiononefive-nC90emPcnKpqBIJrwhWkgQ==/base.apk)
        at org.research.development.versiononefive.WorkerTwo$doWork$2.invokeSuspend(WorkerTwo.kt:19)
 

The delay method name is being mangled to delay-p9JZ4hM, why is this occurring?

UPDATE

I fixed this by adding this to my gradle file

implementation "androidx.work:work-runtime:2.7.0-alpha03"
implementation "androidx.work:work-runtime-ktx:2.7.0-alpha03"

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0-RC"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0-RC"

and refactoring the delay function call like this:-

delay(Duration.seconds(1L)) // CRASH HERE!!!!!!!!!!!!
like image 284
Hector Avatar asked Feb 25 '26 07:02

Hector


2 Answers

Duration is a an inline class (value class in Kotlin 1.5+).

That means that in the JVM there is no Duration class at all. It's represented by a Double (Long in 1.5+) with no wrapper.

When you write a method that takes an inline class as a parameter, Kotlin mangles the name so that it doesn't have the same signature as an overload that takes the underlying value, i.e., so that you can have both delay(Duration) and delay(Double) even though in the JVM the parameter types are the same.

About your error:

As mentioned, inline classes change to value classes in Kotlin 1.5, and there is also a new feature that allows explicitly setting the JVM name of a method.

The likely cause of your error is that you are compiling Kotlin 1.5 and running with libraries from an older version, or vice-versa, and the mangled name of delay is different in one vs the other. Also, the underlying type of Duration has changed, so even if the names matched you wouldn't be able to call the method.

like image 143
Matt Timmermans Avatar answered Feb 28 '26 07:02

Matt Timmermans


I don't see Duration.Companion.seconds method, maybe because I have another Kotlin version. But you can use duration like here:

delay(1.seconds)

Also, you can use time milliseconds:

delay(1000L)
like image 34
Gleb Avatar answered Feb 28 '26 09:02

Gleb



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!