Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.7.0-Beta: NoSuchMethodError: void kotlinx.coroutines.test.TestBuildersKt.runTest$default(kotlinx.coroutines.test.TestScope, long, kotlin.jvm.functions.Function2, int, java.lang.Object) #3673

Closed
alexvanyo opened this issue Mar 10, 2023 · 9 comments · Fixed by #3676 or #3742
Assignees
Labels

Comments

@alexvanyo
Copy link
Contributor

Describe the bug

When updating a project to use kotlinx.coroutines 1.7.0-Beta, existing tests fail with a NoSuchMethodError for a runTest that's being called internally by the Compose test utilities.

The full stack trace looks like the following (but fail for every Compose test):

com.alexvanyo.composelife.resourcestate.ResourceStateComposableTests > collect_as_state_is_correct FAILED
    java.lang.NoSuchMethodError: 'void kotlinx.coroutines.test.TestBuildersKt.runTest$default(kotlinx.coroutines.test.TestScope, long, kotlin.jvm.functions.Function2, int, java.lang.Object)'
        at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.withTestCoroutines(ComposeUiTest.android.kt:342)
        at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.access$withTestCoroutines(ComposeUiTest.android.kt:218)
        at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1$1.invoke(ComposeUiTest.android.kt:294)
        at androidx.compose.ui.test.junit4.IdlingStrategy.withStrategy(IdlingStrategy.android.kt:52)
        at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1.invoke(ComposeUiTest.android.kt:293)
        at androidx.compose.ui.test.junit4.IdlingResourceRegistry.withRegistry(IdlingResourceRegistry.jvm.kt:157)
        at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1.invoke(ComposeUiTest.android.kt:292)
        at androidx.compose.ui.test.junit4.ComposeRootRegistry.withRegistry(ComposeRootRegistry.android.kt:146)
        at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.runTest(ComposeUiTest.android.kt:291)
        at androidx.compose.ui.test.ComposeUiTest_androidKt.runAndroidComposeUiTest(ComposeUiTest.android.kt:107)
        at androidx.compose.ui.test.ComposeUiTest_androidKt.runComposeUiTest(ComposeUiTest.android.kt:63)
        at com.alexvanyo.composelife.resourcestate.ResourceStateComposableTests.collect_as_state_is_correct(ResourceStateComposableTests.kt:39)

Provide a Reproducer

Reproducing PR: alexvanyo/composelife#838

It looks like the update to runTest in 1.7.0-Beta might not have been binary compatible?

@eygraber
Copy link

eygraber commented May 5, 2023

@qwwdfsad I'm still getting this error after updating to 1.7-RC:

'void kotlinx.coroutines.test.TestBuildersKt.runTest$default(kotlinx.coroutines.test.TestScope, long, kotlin.jvm.functions.Function2, int, java.lang.Object)'
java.lang.NoSuchMethodError: 'void kotlinx.coroutines.test.TestBuildersKt.runTest$default(kotlinx.coroutines.test.TestScope, long, kotlin.jvm.functions.Function2, int, java.lang.Object)'
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.withTestCoroutines(ComposeUiTest.android.kt:366)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.access$withTestCoroutines(ComposeUiTest.android.kt:228)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1$1.invoke(ComposeUiTest.android.kt:320)
	at androidx.compose.ui.test.junit4.IdlingStrategy.withStrategy(IdlingStrategy.android.kt:52)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1.invoke(ComposeUiTest.android.kt:319)
	at androidx.compose.ui.test.junit4.IdlingResourceRegistry.withRegistry(IdlingResourceRegistry.jvm.kt:157)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1.invoke(ComposeUiTest.android.kt:318)
	at androidx.compose.ui.test.junit4.ComposeRootRegistry.withRegistry(ComposeRootRegistry.android.kt:146)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.runTest(ComposeUiTest.android.kt:317)
	at androidx.compose.ui.test.junit4.AndroidComposeTestRule$apply$1.evaluate(AndroidComposeTestRule.android.kt:271)

The line it is failing on in ComposeUiTest is:

testCoroutineScope.runTest {}

Is the issue that the defaults are missing?

What's odd is that in the IDE navigating to that runTest goes to:

public fun TestScope.runTest(
    timeout: Duration = DEFAULT_TIMEOUT,
    testBody: suspend TestScope.() -> Unit
): TestResult

@alexvanyo
Copy link
Contributor Author

I am also still seeing this crash in the main 1.7.0 release.

@geranzo
Copy link

geranzo commented May 5, 2023

In 1.7.0 the callstack is:

java.lang.NoSuchMethodError: No static method runTest$default(Lkotlinx/coroutines/test/TestScope;JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)V in class Lkotlinx/coroutines/test/TestBuildersKt; or its super classes (declaration of 'kotlinx.coroutines.test.TestBuildersKt' appears in /data/app/.../base.apk)
at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.withTestCoroutines(ComposeUiTest.android.kt:374)
at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.access$withTestCoroutines(ComposeUiTest.android.kt:234)
at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1$1.invoke(ComposeUiTest.android.kt:326)
at androidx.compose.ui.test.junit4.EspressoLink.withStrategy(EspressoLink.android.kt:66)
at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1.invoke(ComposeUiTest.android.kt:325)
at androidx.compose.ui.test.junit4.IdlingResourceRegistry.withRegistry(IdlingResourceRegistry.jvm.kt:157)
at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1.invoke(ComposeUiTest.android.kt:324)
at androidx.compose.ui.test.junit4.ComposeRootRegistry.withRegistry(ComposeRootRegistry.android.kt:146)
at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.runTest(ComposeUiTest.android.kt:323)
at androidx.compose.ui.test.junit4.AndroidComposeTestRule$apply$1.evaluate(AndroidComposeTestRule.android.kt:271)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:67)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:58)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:446)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2361)

@dkhalanskyjb dkhalanskyjb reopened this May 6, 2023
@dkhalanskyjb
Copy link
Collaborator

Yeah, that's completely on me, I see what went wrong: the overload that I re-introduced accepts a Long and an Integer in Java terms, but should instead accept a long and an int.

Process-wise, since the RC release contained the (incorrect) fix already, we would expect that someone would mention to us that the fix didn't fix anything. That's what RC releases are for. Not sure what we could have done differently with the process.

@tyvsmith
Copy link

tyvsmith commented May 6, 2023

Since @geranzo's stacktrace is slightly different, I'll comment that we're still seeing the originally reported one in the stable release of coroutines 1.7.0 against androidx.compose.ui:ui-test-junit4:1.4.0

java.lang.NoSuchMethodError: 'void kotlinx.coroutines.test.TestBuildersKt.runTest$default(kotlinx.coroutines.test.TestScope, long, kotlin.jvm.functions.Function2, int, java.lang.Object)'
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.withTestCoroutines(ComposeUiTest.android.kt:374)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.access$withTestCoroutines(ComposeUiTest.android.kt:234)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1$1.invoke(ComposeUiTest.android.kt:326)
	at androidx.compose.ui.test.junit4.IdlingStrategy.withStrategy(IdlingStrategy.android.kt:52)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1.invoke(ComposeUiTest.android.kt:325)
	at androidx.compose.ui.test.junit4.IdlingResourceRegistry.withRegistry(IdlingResourceRegistry.jvm.kt:157)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1.invoke(ComposeUiTest.android.kt:324)
	at androidx.compose.ui.test.junit4.ComposeRootRegistry.withRegistry(ComposeRootRegistry.android.kt:146)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.runTest(ComposeUiTest.android.kt:323)
	at androidx.compose.ui.test.junit4.AndroidComposeTestRule$apply$1.evaluate(AndroidComposeTestRule.android.kt:271)
	at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
	at com.ubercab.test.rule.SecurityManagerBasedRule$SecurityManagerStatement.evaluate(SecurityManagerBasedRule.kt:35)
	at com.ubercab.test.rule.SecurityManagerBasedRule$SecurityManagerStatement.evaluate(SecurityManagerBasedRule.kt:35)
	at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
	at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
	at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
	at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
	at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
	at com.ubercab.test.LoggedErrorRule$apply$1.evaluate(LoggedErrorRule.kt:34)
	at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
	at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
	at org.junit.rules.RunRules.evaluate(RunRules.java:20)
	at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:580)
	at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$2(SandboxTestRunner.java:287)
	at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:99)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)

@eygraber
Copy link

eygraber commented May 7, 2023

we would expect that someone would mention to us that the fix didn't fix anything. That's what RC releases are for. Not sure what we could have done differently with the process.

Probably an issue with my setup, but I rely on Renovate to let me know when there are updates. For some reason it didn't let me know about the RC.

@sebaslogen
Copy link
Contributor

After updating to 1.7.0 I also face this problem in my Robolectric tests:

'void kotlinx.coroutines.test.TestBuildersKt.runTest$default(kotlinx.coroutines.test.TestScope, long, kotlin.jvm.functions.Function2, int, java.lang.Object)'
java.lang.NoSuchMethodError: 'void kotlinx.coroutines.test.TestBuildersKt.runTest$default(kotlinx.coroutines.test.TestScope, long, kotlin.jvm.functions.Function2, int, java.lang.Object)'
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.withTestCoroutines(ComposeUiTest.android.kt:374)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.access$withTestCoroutines(ComposeUiTest.android.kt:234)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1$1.invoke(ComposeUiTest.android.kt:326)
	at androidx.compose.ui.test.junit4.IdlingStrategy.withStrategy(IdlingStrategy.android.kt:52)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1.invoke(ComposeUiTest.android.kt:325)
	at androidx.compose.ui.test.junit4.IdlingResourceRegistry.withRegistry(IdlingResourceRegistry.jvm.kt:157)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1.invoke(ComposeUiTest.android.kt:324)
	at androidx.compose.ui.test.junit4.ComposeRootRegistry.withRegistry(ComposeRootRegistry.android.kt:146)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.runTest(ComposeUiTest.android.kt:323)
	at androidx.compose.ui.test.junit4.AndroidComposeTestRule$apply$1.evaluate(AndroidComposeTestRule.android.kt:271)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:589)
	at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$2(SandboxTestRunner.java:290)
	at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:99)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:833)

Code here: https://github.com/sebaslogen/resaca/tree/uptade-coroutines-1.7.0

CI results here: https://github.com/sebaslogen/resaca/actions/runs/4907443414/jobs/8762549032

@dkhalanskyjb
Copy link
Collaborator

As a workaround, could you try to roll back just kotlinx-coroutines-test to 1.6.4, keeping the other coroutines artifacts at 1.7.0?

@sebaslogen
Copy link
Contributor

As a workaround, could you try to roll back just kotlinx-coroutines-test to 1.6.4, keeping the other coroutines artifacts at 1.7.0?

This workaround didn't work for me, even after clean+rebuild in Android Studio 😞

FYI I updated

[versions]
coroutines-test = '1.6.4'
[libraries]
kotlin-coroutines-test = { module = 'org.jetbrains.kotlinx:kotlinx-coroutines-test', version.ref = '1.6.4' }

dkhalanskyjb added a commit that referenced this issue May 12, 2023
Follow-up to #3742.
That implementation there did work around issue #3673, but did not restore full binary compatibility: the wrong value of `dispatchTimeoutMs` was passed. Given how `runTest` was used in the problematic library, it should not be a problem, but just to be safe and establish the same behavior even in the deep corner cases, we restore the original implementation fully.
takahirom added a commit to DroidKaigi/conference-app-2023 that referenced this issue May 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment