Status Update
Comments
hu...@google.com <hu...@google.com> #2
Thanks a lot for the nice reproducible project!
Issue
-
Expected behavior:
androidx.compose.runtime:runtime-android:1.6.3
(for Android) is packaged in the APK -
Actual behavior:
androidx.compose.runtime:runtime-desktop:1.6.3
(for JVM) is packaged in the APK
Root cause
androidx.compose.runtime:runtime:1.6.3
runtime-android
and runtime-desktop
with the following attributes:
Attribute | runtime-android |
runtime-desktop |
---|---|---|
org.gradle.libraryelements | N/A | jar |
org.gradle.category | library | library |
org.gradle.usage | java-runtime | java-runtime |
org.jetbrains.kotlin.platform.type | androidJvm | jvm |
During a build, which one of these two variants is selected depends on the query from the consumer.
- If KGP is not applied in
app
,org.jetbrains.kotlin.platform.type
is not requested in the query, therefore the 2 variants seem equivalent. However, Gradle decides to select theruntime-desktop
variant, probably becauseruntime-desktop
definesorg.gradle.libraryelements = jar
whereasruntime-android
does not define that attribute:
AGP-Library-Bug$ ./gradlew :app:dependencyInsight --dependency androidx.compose.runtime:runtime-desktop:1.6.3 --configuration debugRuntimeClasspath
> Task :app:dependencyInsight
androidx.compose.runtime:runtime-desktop:1.6.3
Variant desktopRuntimeElements-published:
| Attribute Name | Provided | Requested |
|-------------------------------------------------|--------------|--------------|
| org.gradle.libraryelements | jar | |
| org.jetbrains.kotlin.platform.type | jvm | |
| org.gradle.category | library | library |
| org.gradle.usage | java-runtime | java-runtime |
| com.android.build.api.attributes.AgpVersionAttr | | 8.2.2 |
| com.android.build.api.attributes.BuildTypeAttr | | debug |
| org.gradle.jvm.environment | | android |
- If KGP is applied in
app
,org.jetbrains.kotlin.platform.type = androidJvm
is now requested in the query, thereforeruntime-android
is selected, as expected:
> Task :app:dependencyInsight
androidx.compose.runtime:runtime-android:1.6.3
Variant releaseRuntimeElements-published:
| Attribute Name | Provided | Requested |
|-------------------------------------------------|--------------|--------------|
| org.gradle.category | library | library |
| org.gradle.usage | java-runtime | java-runtime |
| org.jetbrains.kotlin.platform.type | androidJvm | androidJvm | => THIS ATTRIBUTE IS REQUESTED IF KGP IS APPLIED
| com.android.build.api.attributes.AgpVersionAttr | | 8.2.2 |
| com.android.build.api.attributes.BuildTypeAttr | | debug |
| org.gradle.jvm.environment | | android |
Workaround
To work around this issue, the users will need to apply KGP in app
(or in any Java module that has this issue).
Fix
The fix is TBD.
ku...@gmail.com <ku...@gmail.com> #3
Thanks for the detailed investigation! Besides applying the Kotlin plugin everywhere (we still have a lot of legacy java modules with no kotlin code), trying this on the same project's app/build.gradle seems to work:
KotlinPlatformType.setupAttributesMatchingStrategy(project.dependencies.attributesSchema)
androidComponents.onVariants { variant ->
variant.components
.flatMap { listOfNotNull(it.runtimeConfiguration, it.compileConfiguration) }
.forEach { configuration ->
configuration.attributes.apply {
attribute(KotlinPlatformType.attribute, KotlinPlatformType.androidJvm)
}
}
}
Though I'm not certain if will miss anything or cause other issues.
ga...@google.com <ga...@google.com> #4
We should add org.gradle.jvm.environment=android
when publishing -android
variants of KMP libs. This attribute is requested by AGP since 4.0+ IIRC.
an...@gmail.com <an...@gmail.com> #5
I'm particularly having issues when integrating our library with ionic and react-native projects right now. as far as I understand this workaround is something that needs to be done in the actual app gradle setup.
au...@google.com <au...@google.com> #6
The issue at hand is that projects that use compose are pulled in by an app project that does not apply Kotlin Gradle Plugin. The workaround is to add a Kotlin Gradle Plugin to the Gradle project that builds the app.
an...@gmail.com <an...@gmail.com> #7
but then the question remais for existing cross platform apps like ionic and rn, they wouldnt normally have Kotlin Gradle Plugin in their main :app module, does that mean that they have to include it in order to use libraries that under the hood rely on androidx compose now?
au...@google.com <au...@google.com> #8
What I suggested in #6 is a workaround, we'll see how we can fix the artifacts to resolve as expected by simply using AGP without KGP.
an...@gmail.com <an...@gmail.com> #9
hm...@google.com <hm...@google.com> #10
Yes, there is a change request with a fix - it is in a process of being reviewed.
sf...@netflix.com <sf...@netflix.com> #11
hm...@google.com <hm...@google.com> #12
This will be fixed in AGP 8.5.0-alpha04 and also will be backported to 8.4.0 RC2 and stable
sf...@netflix.com <sf...@netflix.com> #13
au...@google.com <au...@google.com> #14
It breaks on the consumer side, not the publishing side.
sf...@netflix.com <sf...@netflix.com> #15
So my consumers need to upgrade to AGP 8.4.0 if I want to ship 1.6.x+ in my pom, is that correct?
au...@google.com <au...@google.com> #16
That is correct. Older AGP versions with Kotlin Gradle Plugin applied did not set enough attributes when resolving the dependencies resulting in the wrong platform being picked up.
sf...@netflix.com <sf...@netflix.com> #17
au...@google.com <au...@google.com> #18
The only way for this to work again would be for compose to stop publishing -desktop platform of compose and we don't think we are willing to do that.
How much control do you have over your consumers? You could potentially create a Gradle plugin that tweaks AGP configurations in older versions.
sf...@netflix.com <sf...@netflix.com> #19
au...@google.com <au...@google.com> #20
Yes KGP should just work.
ju...@outsystems.com <ju...@outsystems.com> #21
So is people expected to use Android Studio Jellyfish, which is in beta, to fix the issue?
ju...@outsystems.com <ju...@outsystems.com> #22
hm...@google.com <hm...@google.com> #23
Indeed, 8.3 is the latest stable version at this point. 8.4 (and the corresponding IDE Jellyfish) is still in beta stage as you mentioned. The fix in AGP will go out in 8.4 RC2 (it missed the boat for RC1) and subsequently stable.
an...@gmail.com <an...@gmail.com> #24
js...@google.com <js...@google.com> #25
As
KotlinPlatformType.setupAttributesMatchingStrategy(project.dependencies.attributesSchema)
androidComponents.onVariants { variant ->
variant.components
.flatMap { listOfNotNull(it.runtimeConfiguration, it.compileConfiguration) }
.forEach { configuration ->
configuration.attributes.apply {
attribute(KotlinPlatformType.attribute, KotlinPlatformType.androidJvm)
}
}
}
Gradle's variant resolution is unfortunately very difficult to understand, but essentially this tells gradle to prefer the android artifacts whenever they're available.
ho...@netflix.com <ho...@netflix.com> #26
In essence, asking consumers to upgrade to AGP 8.4 is still a workaround, not a fix.
au...@google.com <au...@google.com> #27
artifacts compatible with ancient versions of AGP other than stop
publishing compose desktop artifacts.
On Thu, Apr 4, 2024, 5:01 PM hokanla <buganizer-system@google.com> wrote:
an...@gmail.com <an...@gmail.com> #28
if I was using androidx directly by myself I would not be complaining too much as there are some ways around it. but since I provide a library that customers use, and some of those customers are React-native, and Ionic (similar to Unity mentioned above) i will have to permanently add this instruction and they will have to implement an extra set of code in their app just to make my library work with their project. It is probably unexpected that such dependency would come from a medium version bump if that makes sense.
Again I'm not sure if there is a better way around it, probably there isnt aside from getting AGP up to that. its just not the reality for most of production projects which tends to lag behind, particularly if we talk about xplatform projects, since people might not even know what gradle is
hm...@google.com <hm...@google.com> #29
As AGP we can't do much about this fact that people can't upgrade to the latest version. Essentially the issue stems from a discrepancy in the way KGP publishes multiplatform libraries and the way AGP consumes them.
This problem is now fixed and in AGP 8.4 RC2 (and 8.5 canary 4).
From KGP side the problem is also fixed - please refer to
Additionally, if you are a library developer and want to target android only you could consider not depending on androidx.compose.runtime:runtime (which exposes -android and -desktop variants) but directly depend on the androidx.compose.runtime:runtime-android (
au...@google.com <au...@google.com> #30
Additionally, if you are a library developer and want to target android only you could consider not depending on androidx.compose.runtime:runtime (which exposes -android and -desktop variants) but directly depend on the androidx.compose.runtime:runtime-android (
https://maven.google.com/web/index.html?#androidx.compose.runtime:runtime-android ) artifact - I think this is should work - feel free to correct me if not.
it does not really work that way as each -android variant will pull in root non-android ones.
an...@gmail.com <an...@gmail.com> #31
so...@google.com <so...@google.com> #32
A postmortem task was automatically filed as a child item to this bug.
an...@google.com <an...@google.com> #33
Thank you for your patience while our engineering team worked to resolve this issue. A fix for this issue is now available in:
- Android Studio Jellyfish | 2023.3.1
- Android Gradle Plugin 8.4.0
We encourage you to try the latest update.
If you notice further issues or have questions, please file a new bug report.
Thank you for taking the time to submit feedback — we really appreciate it!
[Deleted User] <[Deleted User]> #34
Help
[Deleted User] <[Deleted User]> #35
Help
Description
When upgrading Compose from 1.5 -> 1.6, the Application stops working and immediately crashes with:
```
java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/compose/ui/platform/ComposeView;
```
Issue repro:
Build Scan:
The build scan shows that after upgrading to Compose 1.6, the app starts being packaged with `desktop` compose artifacts rather than `android` artifacts. This seems to happen because the application module does not apply the kotlin gradle plugin. Once I apply the kotlin plugin to the app module (even though that would be unnecessary) the issue goes away.
For projects that have a combination of Kotlin/Compose and Java modules, another issue is that the build resolves compose-desktop artifacts during the build process for any java module that happens to have a transient dependency on compose.
STEPS TO REPRODUCE:
1. Create a project with library module (compose + kotlin) and app module (pure Java)
2. Upgrade compose runtime dependencies to 1.6+
3. Observe crash on launch, android compose artifacts not included in APK
------------------
Studio Build: Jellyfish
Version of Gradle Plugin: 8.2.2
Version of Gradle: 8.6
Version of Java: 17
OS: macOS