Skip to content

fix(compose): Publish the foundation-layout floor SentryTraced needs - #6071

Draft
runningcode wants to merge 2 commits into
mainfrom
no/align-compose-foundation-layout-version
Draft

fix(compose): Publish the foundation-layout floor SentryTraced needs#6071
runningcode wants to merge 2 commits into
mainfrom
no/align-compose-foundation-layout-version

Conversation

@runningcode

@runningcode runningcode commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

📜 Description

SentryTraced calls Box, an inline composable, so BoxKt.maybeCachedBoxMeasurePolicy is baked into sentry-compose's own bytecode:

$ javap -c io/sentry/compose/SentryComposeTracingKt.class   # from sentry-compose-android:8.55.0
androidx/compose/foundation/layout/BoxKt.maybeCachedBoxMeasurePolicy:(Landroidx/compose/ui/Alignment;Z)...

That method only exists from foundation-layout 1.7.0 (1.6.3 has rememberBoxMeasurePolicy, 1.5.4 also has boxMeasurePolicy). But androidMain reaches the class transitively through compileOnly(material3), so the published POM declares no compose dependency at all - only sentry, sentry-android-navigation and lifecycle-common-java8.

This PR:

  • Publishes a dependency constraint on foundation-layout:1.7.0 from sentry-compose. A constraint rather than a dependency, so apps that never touch SentryTraced are not pulled onto compose. It lands in both the GMM (releaseApiElements-published and releaseRuntimeElements-published) and the POM as <dependencyManagement>.
  • Raises androidxCompose 1.6.3 -> 1.7.0 so the catalog states the version we actually resolve.
  • Raises androidxNavigation 2.4.2 -> 2.8.0, the first release that stops requesting compose 1.0.1.
  • Drops implementation(libs.androidx.compose.foundation) from sentry-compose's androidUnitTest, added in fix(compose): Stop SentryTraced from reusing stale parent spans #6057 purely to drag the androidx constraint onto the test graph. The tests only use androidx.compose.foundation.layout.*.

One limit worth knowing: a consumer that strictly pins foundation-layout below 1.7.0 still wins (Gradle reports it as "By ancestor") and is back to a NoSuchMethodError. Nothing publishable can override a root-level strict pin. The constraint covers plain version requests, which is the case that actually bites. The POM's <dependencyManagement> entry is likewise decorative for Maven consumers, since Maven does not inherit dependency management from a transitive dependency's POM — not a concern for Android consumers, who are all on Gradle.

💡 Motivation and Context

A consumer resolving foundation-layout 1.6.x hits NoSuchMethodError at runtime, with nothing in our metadata to warn them.

Our own build had the same latent skew - three versions across three classpaths of one module:

classpath before after
releaseCompileClasspath 1.8.1 1.8.1
releaseUnitTestCompileClasspath 1.6.3 1.7.0
releaseUnitTestRuntimeClasspath 1.7.0 1.7.0

The catalog's 1.6.3 was only a request, and it kept losing. The runtime 1.7.0 came from an unrelated androidx constraint published by compose-ui on foundation (reason: "prevents a regression in Overscroll"), which lives in releaseRuntimeElements-published only - hence runtime lifted, compile did not. foundation-layout then followed via the atomic-group constraint. That accident is what kept SentryTracedTest green; nothing in our build asked for it, and navigation:2.4.2's request for 1.0.1 was pushing the other way.

dependencyInsight now names our own reason instead:

androidx.compose.foundation:foundation-layout:1.7.0
   Selection reasons:
      - By constraint: SentryTraced inlines Box, whose BoxKt.maybeCachedBoxMeasurePolicy only exists from 1.7.0

1.7.0 is a truthful floor: every foundation-layout symbol the built AAR references (maybeCachedBoxMeasurePolicy, rowMeasurePolicy, SpacerKt.Spacer, Arrangement, BoxScopeInstance, RowScopeInstance) resolves against the 1.7.0 jar with matching descriptors, even though the main compile classpath is still 1.8.1 via material3:1.4.0.

💚 How did you test it?

Unit tests for sentry-compose, sentry-android-navigation, sentry-android-core and sentry-android-replay; assembled the Android sample and both UI-test apps against the new navigation and compose versions; lint and detekt on sentry-compose. apiDump produced no changes.

Published to mavenLocal and resolved from a throwaway AGP 9.2.1 consumer with two build types and two product flavors, to confirm the constraint behaves per-variant:

consumer result
all 4 variants x compile + runtime, declaring 1.6.3 raised to 1.7.0, reason attributed to the constraint
freeImplementation 1.6.3 / paidImplementation 1.8.1 free -> 1.7.0, paid stays 1.8.1 (floor, not force)
no compose dependency at all no androidx.compose on the graph; constraint inert
strictly("1.6.3") stays 1.6.3 (see caveat above)

The published variants carry no BuildTypeAttr or flavor attributes, so a consumer's debug and flavored variants all match the single published release variant and pick up the constraint.

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.

🔮 Next steps

The main compile classpath still resolves foundation-layout 1.8.1 through material3:1.4.0 while we declare a 1.7.0 floor. That is safe today, but a Compose BOM would collapse androidxCompose, material3, material-icons and ui-test-junit4 into one number and remove the class of problem - out of scope here.

SentryTraced calls Box, an inline composable, so BoxKt.maybeCachedBoxMeasurePolicy
ends up baked into sentry-compose's own bytecode. That method only exists from
foundation-layout 1.7.0, yet androidMain reaches the class transitively through
compileOnly(material3), so the published metadata named no compose dependency at
all. A consumer resolving foundation-layout 1.6.x got a NoSuchMethodError with
nothing to warn them.

Publish a dependency constraint rather than a dependency, so apps that never touch
SentryTraced are not pulled onto compose.

Our own build had the same skew. The catalog asked for 1.6.3 while the unit test
runtime only reached 1.7.0 by way of an unrelated androidx constraint on
foundation ("prevents a regression in Overscroll"), one that navigation 2.4.2's
request for 1.0.1 was quietly losing to. Raise the catalog to 1.7.0 and navigation
to 2.8.0, the first release that stops asking for compose 1.0.1, so the resolved
version is the one we declare. The androidUnitTest foundation dependency added in
#6057 only existed to drag that constraint onto the test graph.
@sentry

sentry Bot commented Sep 8, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.55.0 (1) release

⚙️ sentry-android Build Distribution Settings

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

Successfully merging this pull request may close these issues.

1 participant