getsentry / getsentry/sentry-java

NoSuchMethodError in SentryTraced on Compose < 1.8 (inlined Box pulls in newer internals)

Abierto
#5,885 1 comentario 0 reacciones 1 asignado Reclamado por @runningcode Ver en GitHub
Jetpack Compose Platform: Android Platform: Java Type: Bug
Lenguaje dominante
Kotlin
Estrellas
1.4k
Forks
478
Merge medio
2 d 23 h
PR fusionados (30 d)
67

Descripción

## Summary

`sentry-compose` ships bytecode that references Jetpack Compose *internal* APIs newer than the SDK's own declared Compose floor (`androidxCompose = "1.6.3"` in `gradle/libs.versions.toml`). Apps resolving an older Compose crash with `NoSuchMethodError` when composing `SentryTraced`.

Sentry issue: [SDK-CRASHES-JAVA-48AR]() — 157 occurrences, first seen 2026-03-19, reported on release 8.51.0.

## Root cause

`androidx.compose.foundation.layout.Box` is an **inline** composable. The Compose compiler bakes its body into *our* bytecode, so `sentry-compose` calls Compose internals directly rather than calling `BoxKt.Box`. The published 8.51.0 `SentryComposeTracingKt` contains zero `BoxKt.Box` call sites and instead references:

| Symbol | First available in |
| -- | -- |
| `BoxKt.maybeCachedBoxMeasurePolicy` | foundation-layout **1.7.0** |
| `Composer.shouldExecute` | runtime **1.8.0** |

Neither exists on Compose 1.6.x, so the call fails at runtime at the `SentryTraced` frame.

`SentryUserFeedbackButtonKt` is affected the same way (it also emits `shouldExecute` / `materializeModifier`).

## How it regressed

`sentry-compose/build.gradle.kts` declares `compileOnly(libs.androidx.compose.material3)`. In #5017 (*"Convert main screen to Jetpack Compose"* — a **samples** refactor) material3 was bumped `1.2.1 -> 1.4.0`. material3 1.4.0 transitively pulls foundation-layout 1.8.1 and runtime 1.9.0 onto `sentry-compose`'s compile classpath, silently raising the floor of the inlined code.

Confirmed by bisecting published artifacts on Maven Central:

* 8.31.0 and earlier -> `rememberBoxMeasurePolicy` (works on 1.6.x)
* **8.32.0** onward -> `maybeCachedBoxMeasurePolicy` + `shouldExecute`

## Note on the Seer suggestion

Seer's autofix suggests removing `propagateMinConstraints = true` from the `Box` in `SentryTraced`. **This is incorrect.** `BoxKt`'s public signature is byte-for-byte identical from foundation-layout 1.5.4 through 1.11.2 — `propagateMinConstraints` has always been a parameter. Removing it would change layout behavior (regressing #2637) without fixing the crash.

## Proposed fix

Decouple `sentry-compose`'s compile-time Compose floor from material3. Add a dedicated version-catalog entry pinned to the oldest supported material3 and use it only for `sentry-compose`'s `compileOnly`, mirroring the existing `androidx-compose-ui-replay` entry (which already carries a *"don't change without testing forwards compatibility"* comment):

```kotlin
// sentry-compose/build.gradle.kts
compileOnly(libs.androidx.compose.material3.compat) // pinned to 1.2.1
```

Pinning `libs.androidx.compose.material3` globally is not viable — the samples depend on newer material3 APIs and material icons.

### Verified locally

Compiling `sentry-compose` with material3 pinned to 1.2.1:

* `:sentry-compose:compileReleaseKotlinAndroid` succeeds
* emitted bytecode reverts to `rememberBoxMeasurePolicy`, and `shouldExecute` / `materializeModifier` are gone from both affected classes
* `rememberBoxMeasurePolicy` is present in foundation-layout 1.5.4 through 1.11.2, so it is both backward and forward compatible

## Follow-up: add a regression guard

Nothing in CI asserts the supported Compose floor, which is why this shipped silently and went unnoticed for ~19 releases. We should add a guard so the next transitive bump can't reintroduce it — either a check that resolves the floor versions, or an assertion over the compiled bytecode for newer-than-floor internal symbols.

## Open decision

Alternative: **raise** the documented floor to Compose 1.8.0 instead of restoring 1.6.3 compatibility. That is simpler, but is a breaking change for users on older Compose and needs a changelog entry and an explicit minimum-version statement.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.