sharedUserId breaks Compose Resources on Android
Describe the bug
Compose Resources fails to load resources on Android when the application is using a sharedUserId
Affected platforms
- Android
Versions
- Kotlin version*: 1.9.23
- Compose Multiplatform version*: 1.6.2
- OS version(s)*: tested on Android 13 and 14, but likely affects all versions
- OS architecture (x86 or arm64): tested on arm64, but likely affects x86 as well
- Device (model or simulator for iOS issues): OnePlus 7 Pro (GM1917) and Samsung Galaxy s24 Ultra (SM-S928U1)
- JDK (for desktop issues): N/A
To Reproduce
Minimal reproducer using kmp.jetbrains.com's Android template:
https://github.com/garrison-henkle/composeResourcesSharedUserIdBug
Stacktrace is also in the above repo's README.md
Steps:
- Launch the application with the
sharedUserIdattribute in theManifest.xml.
Expected behavior
The app is able to load resources regardless of whether it uses a sharedUserId or not
Screenshots N/A
Additional context
I maintain an application that has unfortunately inherited a sharedUserId. My team has been building out a replacement app using Compose Mutliplatform, and we recently added in the sharedUserId to prepare it for submission to the Play Store. The addition of the sharedUserId prevents the app from loading any images or strings (fonts load fine because the underlying implementation delegates to Android's asset loader).
I investigated the issue and narrowed it down to the class loader. Removing Thread.currentThread().contextClassLoader from ResourceReader.android.kt seemed to fix the issue for me:
// Before (crashes)
private fun getClassLoader(): ClassLoader {
return Thread.currentThread().contextClassLoader ?: this.javaClass.classLoader!!
}
// After (runs)
private object ResourceReader
private fun getClassLoader(): ClassLoader {
return ResourceReader.javaClass.classLoader!!
}
I know essentially nothing about class loaders, so I don't know the implications of just removing the Thread's context class loader here. Hopefully the above hack at least demonstrates what's causing the issue 😅
Thanks!
@terrakok, it is reproduced on the provided project. sharedUserId is deprecated, but it isn't possible to migrate old projects that needs to be maintained. Can we use the suggested fix?
The classloader logic was implemented by intention here: https://github.com/JetBrains/compose-multiplatform/pull/2490
I will investigate it more because it seems suspicious
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.