Skip to content

Android app with coroutines 0.30.1-eap13 crashes in runtime #657

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

Closed
trashkalmar opened this issue Oct 3, 2018 · 22 comments
Closed

Android app with coroutines 0.30.1-eap13 crashes in runtime #657

trashkalmar opened this issue Oct 3, 2018 · 22 comments
Assignees

Comments

@trashkalmar
Copy link

java.lang.IllegalStateException: Module with Main dispatcher is missing. Add dependency with required Main dispatcher, e.g. 'kotlinx-coroutines-android'
        at kotlinx.coroutines.Dispatchers.getMain(Dispatchers.kt:61)

kotlinx-coroutines-android is obviously added.
Version 0.30.0-eap13 works fine.

@qwwdfsad
Copy link
Collaborator

qwwdfsad commented Oct 3, 2018

Could you please provide a self-contained example? Or check why loadMainDispatcher loads nothing?

@trashkalmar
Copy link
Author

trashkalmar commented Oct 3, 2018

Could you please provide a self-contained example?

It is enough to start any coroutine in UI context. For example:
GlobalScope.launch(Dispatchers.Main) { ... }

Or check why loadMainDispatcher loads nothing?

ServiceLoader is unable to load MainDispatcherFactory.

@qwwdfsad
Copy link
Collaborator

qwwdfsad commented Oct 3, 2018

It is enough to start any coroutine in UI context.

I did it in sample Android project and it works in both debug and release mode.

ServiceLoader is unable to load MainDispatcherFactory.

Again, works on my machine.

Please be cooperative. I'm willing to help you, but I can't do anything with reports like "it doesn't work"

@trashkalmar
Copy link
Author

It was my fault. I've excluded some Kotlin meta files from APK (specifically, Meta-inf/services/**). It was safe for previous coroutines version, but for 0.30.1 it became destructive.
Sorry that wasted your time.

@trashkalmar
Copy link
Author

trashkalmar commented Oct 4, 2018

If an app is obfustacted with default proguard settings, it crashes in runtime. Here is sample project to reproduce an issue: https://www.dropbox.com/s/eay696h9qmxjl5e/sample.zip?dl=1
UPD: I've created PR #662 but it will not work, because @Keep annotation is Android specific.
Is the only way to add proguard rules?

-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}

@trashkalmar trashkalmar reopened this Oct 4, 2018
@ghost
Copy link

ghost commented Oct 12, 2018

I had this bug when exported file apk when using proguard with the version 0.30.2.

@qwwdfsad qwwdfsad self-assigned this Oct 12, 2018
@petitJAM
Copy link

petitJAM commented Oct 12, 2018

Those proguard rules didn't work for me, so I used this:

-keepnames class kotlinx.** { *; }

Definitely not a great solution since it tells proguard to keep everything, but it works.

@bernaferrari
Copy link

Same issue here with 0.30.2.

@jvlad
Copy link

jvlad commented Oct 15, 2018

The same issue with 0.30.1 in release build only (i. e. when minifyEnabled true is specified)

Android Studio 3.1.2
Build #AI-173.4720617, built on April 14, 2018
JRE: 1.8.0_152-release-1024-b01 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Mac OS X 10.13.4

Didn't work:

-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}

Worked:

-keepnames class kotlinx.** { *; }

@qwwdfsad
Copy link
Collaborator

qwwdfsad commented Oct 15, 2018

Thank you @trashkalmar for the reproducer.
Jettifier seems to have an issue with ServiceLoader and name mangling.

I have (ugly as hell) fix which first tries to lookup main dispatcher in service loader and then invokes Class.forName("...") for android factory. It will be fixed in 1.0.0-RC

@bernaferrari
Copy link

This happens to me even without jetfier. Just proguard on its enough.

@AAverin
Copy link

AAverin commented Oct 21, 2018

It would be great if kotlinx.coroutines library could include proguard rules as part of distribution

@AAverin
Copy link

AAverin commented Oct 22, 2018

@bernaferrari then they need to be updated to

-keepnames class kotlinx.** { *; }

for kotlinx-coroutines-android

@JakeWharton
Copy link
Contributor

JakeWharton commented Oct 22, 2018 via email

@ghost
Copy link

ghost commented Oct 26, 2018

I have the same issue with 0.30.2

I also get default rule at
https://github.com/Kotlin/kotlinx.coroutines/blob/master/core/kotlinx-coroutines-core/resources/META-INF/proguard/coroutines.pro

Got the same message @trashkalmar

-keepnames class kotlinx.** { *; } did work though

@dtunctuncer
Copy link

I still have error even though I used suggested ProGuard rules

@djrsousa
Copy link

djrsousa commented Dec 24, 2018

The suggested proguard rules should be enough. I mean:

# ServiceLoader support
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}

# Most of volatile fields are updated with AFU and should not be mangled
-keepclassmembernames class kotlinx.** {
    volatile <fields>;
}

I was recently facing this issue and realised that it was my fault and nothing to do with the proguard rules. Basically, we were re-signing the apk and removing the META-INF folder in the process. So, for the ones that are still facing the issue, please make sure that you are not doing the same (re-signing your apk and removing the META-INF folder after the release build is done). If that's the case, I would suggest you to generate an unsigned build and sign it afterwards.

Just for reference, I'm using the version 1.0.1.
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1")

Hope it helps.

@josselinPello
Copy link

We were having this crash without even using ProGuard 😅 As mentioned by @djrsousa, it's because we were:

Signing the APK twice,

and replacing the META-INF folder in the process...

@endru-kargo
Copy link

In our case, we put signingConfigs in the gradle file, then use the Generate Signed Bundle / APK to create the bundle. :D
Removing the signingConfigs solves the problem.

@Panajev
Copy link

Panajev commented May 14, 2019

@djrsousa thanks for spelling out the issue so well. Wished I had seen it before spending extra time researching the issue, but it was a good experience nonetheless.
Your suggestions, or moving to letting your build.gradle specify how to sign the app in debug and release modes, work, but if people still want to follow their current re-signing flow, they could delete only few files in the META-INF folder instead of all the files:

zip -d "$apkInputFullPath" META-INF/\*.RSA
zip -d "$apkInputFullPath" META-INF/\*.SF
zip -d "$apkInputFullPath" META-INF/\*.MF

Unless I am missing something, this should do the trick and be a very minimal change to the script people might be already running. Those files are the only ones that get added / modified when the signing occurs from what we could see.

@skywalkerhbz
Copy link

skywalkerhbz commented Oct 8, 2019

We were having this crash without even using ProGuard 😅 As mentioned by @djrsousa, it's because we were:

Signing the APK twice,

and replacing the META-INF folder in the process...

How can i sign the apk twice,but just replace the signature files in the META-INF folder?
Please... this confused me some days....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests