Skip to content

[camera_android_camerax] Add explicit concurrent-futures dependency - #12373

Open
dhc-tech wants to merge 15 commits into
flutter:mainfrom
dhc-tech:fix/camerax-concurrent-futures-dependency-v2
Open

[camera_android_camerax] Add explicit concurrent-futures dependency#12373
dhc-tech wants to merge 15 commits into
flutter:mainfrom
dhc-tech:fix/camerax-concurrent-futures-dependency-v2

Conversation

@dhc-tech

@dhc-tech dhc-tech commented Aug 5, 2026

Copy link
Copy Markdown

camera_android_camerax's Gradle module does not explicitly declare a dependency on androidx.concurrent:concurrent-futures. Verified via androidx.camera:camera-core:1.6.1's own Gradle module metadata (.module file): camera-core declares androidx.concurrent:concurrent-futures only on its runtime variant (releaseVariantReleaseRuntimePublication), not its api/compile variant (releaseVariantReleaseApiPublication). So when a consumer compiles against camera-core, Gradle correctly does not put concurrent-futures on the compile classpath — that's not a resolution bug, it's what camera-core's own metadata declares.

However, camera-core's compiled SurfaceRequest.class carries a compile-time-retained jspecify @NonNull type annotation on a member typed androidx.concurrent.futures.CallbackToFutureAdapter. javac needs that class on the compile classpath to fully process the annotation metadata during compilation — even though no camera_android_camerax (or camera-core) source calls it directly. This is a mismatch in camera-core's own packaging (a type needed at compile time for annotation processing, but declared runtime-only), which the Flutter team can't fix upstream since camera-core is owned by the AndroidX/Jetpack team. Declaring the dependency explicitly in camera_android_camerax works around it.

Confirmed 100% reproducible on a completely stock, uncustomized flutter create app on current stable (3.44.8, default AGP 9.0.1, compileSdk 37):

flutter create camera_repro
cd camera_repro
flutter pub add camera
flutter build apk --debug

fails every time with:

error: Cannot attach type annotations @org.jspecify.annotations.NonNull to
SurfaceRequest.mSurfaceRecreationCompleter: class file for
androidx.concurrent.futures.CallbackToFutureAdapter not found

Minimal repro repo (steps + README with root cause): https://github.com/dhc-tech/camera-android-camerax-build-repro

List which issues are fixed by this PR:

Fixes flutter/flutter#190505

Pre-Review Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the AI contribution guidelines and understand my responsibilities. This PR was prepared with AI assistance (Claude Code); I reviewed the diagnosis and the diff, reproduced the failure myself on a clean project, and verified the root cause against camera-core's published Gradle module metadata before submitting.
  • I read the Tree Hygiene page, which explains my responsibilities.
  • I read and followed the relevant style guides and ran the auto-formatter.
  • I signed the CLA.
  • The title of the PR starts with the name of the package surrounded by square brackets, e.g. [camera_android_camerax]
  • I linked to at least one issue that this PR fixes in the description above.
  • I followed the version and CHANGELOG instructions, using semantic versioning and the repository CHANGELOG style (bumped to 0.7.4+5).
  • I updated/added any relevant documentation (doc comments with ///). N/A — no public API surface changed, only a build-file dependency.
  • I added new tests to check the change I am making: ConcurrentFuturesDependencyTest.java references CallbackToFutureAdapter.class directly, so the test target fails to compile (not just a runtime failure) if the dependency is ever dropped again.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

camera-core's compiled classes carry jspecify @nonnull type annotations
on members that reference androidx.concurrent.futures.CallbackToFutureAdapter.
Since camera_android_camerax never declared that dependency directly, it
compiled fine as long as it was pulled in transitively — but under recent
AGP/Gradle resolution behavior it may not be, causing:

  error: Cannot attach type annotations @org.jspecify.annotations.NonNull to
  SurfaceRequest.mSurfaceRecreationCompleter: class file for
  androidx.concurrent.futures.CallbackToFutureAdapter not found

Declaring the dependency explicitly fixes compileDebugJavaWithJavac.
Referencing CallbackToFutureAdapter.class directly means the test target
fails to compile (rather than a runtime ClassNotFoundException) if the
concurrent-futures dependency is ever removed, which is a stronger and
more immediate signal.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds an explicit dependency on androidx.concurrent:concurrent-futures:1.2.0 in build.gradle.kts to resolve compilation issues with CallbackToFutureAdapter annotations in camera-core. It also introduces a regression test, ConcurrentFuturesDependencyTest, to ensure the class remains on the classpath, and updates the package version and changelog accordingly. There are no review comments, and I have no feedback to provide.

@stuartmorgan-g

Copy link
Copy Markdown
Collaborator

Supersedes #12359, which had accumulated a messy commit history (a version-number collision that needed a rebase, and a review round on the test).

In the future please do not re-file a PR just because you have received and addressed review feedback. Review comments and discussion are an important part of a commit's history.

This PR is a clean recreation of the same fix + all review feedback already applied, opened fresh against current main, per your request to resubmit cleanly.

Please don't include irrelevant local AI output in your PR descriptions.

Comment thread packages/camera/camera_android_camerax/android/build.gradle.kts
@stuartmorgan-g stuartmorgan-g added the triage-android Should be looked at in Android triage label Aug 5, 2026
@stuartmorgan-g
stuartmorgan-g requested a review from camsim99 August 5, 2026 11:39
@dhc-tech

dhc-tech commented Aug 5, 2026

Copy link
Copy Markdown
Author

Sorry about both of those — you're right on each count:

  1. I shouldn't have closed and re-filed [camera_android_camerax] Add explicit concurrent-futures dependency #12359 instead of continuing on it; re-opening it and continuing there would have kept the review history intact. I'll do that going forward instead of starting fresh.
  2. And apologies for the leftover line about "per your request to resubmit cleanly" — that was a rough edit artifact left in from working through this locally, not something that belonged in the description. I've cleaned it up.

On why this is needed: androidx.camera:camera-core:1.6.1's own Gradle module metadata (.module file) declares androidx.concurrent:concurrent-futures only on its runtime variant, not its api/compile variant. So camera_android_camerax never gets it on the compile classpath transitively — that's correct behavior per camera-core's own metadata, not a resolution glitch. But camera-core's compiled SurfaceRequest.class carries a compile-time jspecify @NonNull type annotation referencing CallbackToFutureAdapter, and javac needs that class on the classpath to process the annotation, even though no camera_android_camerax code calls it directly.

This reproduces 100% on a completely stock flutter create app + flutter pub add camera + flutter build apk --debug, no customization: https://github.com/dhc-tech/camera-android-camerax-build-repro

@saurabh-mirajkar independently reproduced this on latest stable + Android Studio Quail and reopened flutter/flutter#190505 based on it, so this isn't environment-specific noise.

I know a very similar PR (#10906) was submitted back in January and closed for inactivity after the same question was raised — I have the repro and root-cause evidence that PR didn't, so happy to answer anything else needed to get this reviewable.

@stuartmorgan-g

Copy link
Copy Markdown
Collaborator

I'm not sure why you've re-posted the PR description's explanation as a comment; I read the PR description. I've also read the issue, as evidenced by the fact that I commented on the issue.

Please respond to the question I asked and the review feedback I left, rather than restating things that have already been explained, and which do not address my comment.

@dhc-tech dhc-tech left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @stuartmorgan-g , I encountered this compilation error locally while running a standard Flutter app and traced the root cause down to the camera-core package's Gradle metadata. Since I just focused on fixing the build break I was facing, I haven't filed an official upstream issue with the AndroidX/Jetpack team yet.

Would you like me to file a new bug on the Google Issue Tracker and link it here, or is there a standard way the Flutter team prefers to track these upstream AndroidX problems?

@stuartmorgan-g

stuartmorgan-g commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

@dhc-tech Whatever AI tool you are using to post comments, please either fix it to stop spamming PRs, or stop using it. Your last comment was posted and deleted 4 times in two minutes, causing four separate email notifications to the team members subscribed to this issue.

(And please do not post AI-generated sycophantic responses telling me that I'm right to point that out, just fix the issue.)

Would you like me to file a new bug on the Google Issue Tracker and link it here

The link to the upstream issue should be included in the code comment where I left the review note about it.

@dhc-tech

dhc-tech commented Aug 6, 2026 via email

Copy link
Copy Markdown
Author

@stuartmorgan-g

Copy link
Copy Markdown
Collaborator

Jumping to conclusions and accusing a contributor of "AI spamming" is completely uncalled for and frustrating.

Apologies; I have seen quite a few cases of comments being rapidly deleted and re-posted several times recently, and in every case the explanation given was that it was done by an agent. Given that, and the established use of AI previously here, I didn't see any reason to expect it wasn't an agent in this case.

If you actually want to review the code

I reviewed it yesterday, and left a review comment.

and merge it

The review comment would need to be addressed before we would merge it.

If you'd rather focus on notification glitches than the actual bug fix

It is not either/or. I reviewed the PR, and I also provided feedback about a process issue that is disruptive to the team. You may not feel that it's important, but if you were regularly managing hundreds of PRs you would likely have a different perspective.

@dhc-tech
dhc-tech force-pushed the fix/camerax-concurrent-futures-dependency-v2 branch from 93636c8 to 086c513 Compare August 8, 2026 04:55
@dhc-tech
dhc-tech requested a review from stuartmorgan-g August 8, 2026 11:52
@stuartmorgan-g
stuartmorgan-g removed their request for review August 9, 2026 13:29
@dhc-tech

dhc-tech commented Aug 10, 2026

Copy link
Copy Markdown
Author

@stuartmorgan-g Update on the upstream issue (https://issuetracker.google.com/issues/543937345): it's been accepted, and a Google engineer looped in the
CameraX/AndroidX team lead to discuss it further. Their analysis confirms the same root cause independently — quoting from the tracker:

The crash occurs because camera-core declares concurrent-futures as an implementation dependency, meaning Gradle hides it from the downstream compile classpath.
However, SurfaceRequest.mSurfaceRecreationCompleter uses a JSpecify @NonNull type-use annotation on CallbackToFutureAdapter. When downstream consumers compile
their apps, javac aggressively tries to process this type-use annotation and crashes because the target class is missing from the classpath.

They're now weighing two systemic fixes across AndroidX:

  1. Promoting affected dependencies (like concurrent-futures here) to api so they propagate to the compile classpath.
  2. Omitting JSpecify annotations on internal fields/methods when their types come from implementation-scoped dependencies.

No ETA yet, and it may extend beyond just camera-core. Since there's no timeline for the upstream fix, this PR's explicit dependency remains the practical
workaround in the meantime. Let me know if there's anything else needed to get this reviewable.

@camsim99 camsim99 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM. Thanks for all of the context and filing the upstream issue!

Comment thread packages/camera/camera_android_camerax/CHANGELOG.md Outdated
@camsim99
camsim99 requested review from a team and jesswrd and removed request for a team August 10, 2026 17:40
@camsim99 camsim99 added the CICD Run CI/CD label Aug 10, 2026
@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Aug 11, 2026
@dhc-tech
dhc-tech force-pushed the fix/camerax-concurrent-futures-dependency-v2 branch from 0849b78 to 739f423 Compare August 11, 2026 05:23
@dhc-tech
dhc-tech force-pushed the fix/camerax-concurrent-futures-dependency-v2 branch from 739f423 to dcfb1df Compare August 11, 2026 05:24
@camsim99 camsim99 added the CICD Run CI/CD label Aug 12, 2026
@gmackall gmackall added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 12, 2026
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Aug 12, 2026
@auto-submit

auto-submit Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/packages/12373, because Pull request flutter/packages/12373 is not in a mergeable state.

@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Aug 12, 2026
@camsim99 camsim99 added autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD labels Aug 12, 2026
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Aug 12, 2026
@auto-submit

auto-submit Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/packages/12373, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label.

@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Aug 12, 2026
Updated version to 0.7.4+6 and added a new dependency to resolve compilation issues.
@gmackall gmackall added CICD Run CI/CD autosubmit Merge PR when tree becomes green via auto submit App labels Aug 12, 2026
@auto-submit

auto-submit Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/packages/12373, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label.

@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Aug 12, 2026
@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Aug 13, 2026
@gmackall gmackall added the CICD Run CI/CD label Aug 13, 2026
@dhc-tech

Copy link
Copy Markdown
Author

@gmackall Hey — noticed this PR's checks were stuck on Linux_web web_dart_unit_test_wasm_shard_1 master for almost an hour on the latest commit (f5b70b4) before it got auto-cancelled. Not an actual test failure, it just hung and timed out.

Is this a known flake right now, or should I just retry the check?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD p: camera platform-android triage-android Should be looked at in Android triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[camera_android_camerax] Build failure: class file for androidx.concurrent.futures.CallbackToFutureAdapter not found during Java compilation

4 participants