Android HolisticLandmarker 1.0.0 crashes: Any$Builder.build() NoSuchMethodError with protobuf-javalite
Have I written custom code (as opposed to using a stock example script provided in MediaPipe)
Yes
OS Platform and Distribution
Android 15 (physical device, MIUI-based), also reproduced on a clean AGP/Gradle setup with no other change to the official examples/holistic_landmarker/android sample's dependency setup besides the version bump described below.
Mobile device if the issue happens on mobile device
Physical Android device (arm64-v8a)
Browser and version if the issue happens on browser
No response
Programming Language and version
Kotlin / Java (Android), Kotlin 2.4.0
MediaPipe version
1.0.0
Bazel version
N/A (Gradle build, not Bazel) — Gradle 9.3.1, AGP 8.11.1
Solution
Holistic (HolisticLandmarker)
Android Studio, NDK, SDK versions (if issue is related to building in Android environment)
compileSdk 35, minSdk 24, targetSdk 35. Standard Flutter/Gradle Android build (no NDK involved on the Java/Kotlin side).
Xcode & Tulsi version (if issue is related to building for iOS)
No response
Describe the actual behavior
Calling HolisticLandmarker.createFromOptions(context, options) (LIVE_STREAM mode, options built exactly as in the official HolisticLandmarkerHelper.kt sample) throws:
java.lang.NoSuchMethodError: No virtual method build()Lcom/google/protobuf/Any; in class Lcom/google/protobuf/Any$Builder; or its super classes (declaration of 'com.google.protobuf.Any$Builder' appears in <app>.apk)
at com.google.mediapipe.tasks.vision.holisticlandmarker.HolisticLandmarker$HolisticLandmarkerOptions.convertToAnyProto(HolisticLandmarker.java:620)
at com.google.mediapipe.tasks.core.TaskInfo.generateGraphConfig(TaskInfo.java:125)
at com.google.mediapipe.tasks.core.TaskRunner.create(TaskRunner.java:82)
at com.google.mediapipe.tasks.core.TaskRunner.create(TaskRunner.java:58)
at com.google.mediapipe.tasks.vision.holisticlandmarker.HolisticLandmarker.createFromOptions(HolisticLandmarker.java:250)tasks-core:1.0.0's own POM declares a compile dependency on com.google.protobuf:protobuf-javalite:4.26.1. With that (declared) version present, HolisticLandmarker.createFromOptions always throws the above. I tested the entire available protobuf-javalite version range to rule out a simple version-pinning issue (as in the historical #2456, which was the opposite direction and was fixed by MediaPipe switching solution-core from full to lite protobuf):
| protobuf-javalite version | Result |
|---|---|
| 3.25.5 | NoSuchMethodError (same as above) |
| 4.26.1 (declared by tasks-core's own POM) | NoSuchMethodError (same as above) |
| 4.28.0 | NoSuchMethodError (same as above) |
| 4.36.0 (latest as of writing) | NoSuchMethodError (same as above) |
None of these provide a com.google.protobuf.Any$Builder.build() method with the signature MediaPipe's compiled bytecode expects. This looks like HolisticLandmarkerOptions.convertToAnyProto (and likely other tasks-core code building Any protos) was actually compiled/linked against full protobuf-java, not protobuf-javalite, and the POM's declared protobuf-javalite dependency is simply the wrong artifact for this release.
The only configuration that actually works is excluding protobuf-javalite entirely and depending on full protobuf-java instead (exactly what examples/holistic_landmarker/android/app/build.gradle in this repo already does — I initially assumed that was legacy/defensive boilerplate, but it turns out to be load-bearing and required, not optional, and is currently undocumented there).
Describe the expected behaviour
HolisticLandmarker.createFromOptions should succeed using the dependency set declared by tasks-core's own POM (i.e. implementation("com.google.mediapipe:tasks-vision:1.0.0") alone, with no manual exclude/protobuf-java swap), OR the POM should declare protobuf-java (full) as the actual required dependency so Gradle resolves correctly without a manual workaround.
This matters beyond convenience: requiring full protobuf-java makes tasks-vision:1.0.0 incompatible with any app that also depends on Firebase Firestore (com.google.firebase:firebase-firestore, via protolite-well-known-types + grpc-protobuf-lite), since Firestore requires protobuf-javalite and full/lite protobuf cannot coexist on one classpath (confirmed: forcing full protobuf-java app-wide fails at mergeDebugJavaResource with duplicate google/protobuf/descriptor.proto between protobuf-java and protolite-well-known-types). This is the same underlying class of conflict tracked in firebase/firebase-android-sdk#5997, #6359 and protocolbuffers/protobuf#18127, just triggered from the MediaPipe side this time.
Standalone code/steps you may have used to try to get what you need
app/build.gradle:dependencies { implementation 'com.google.mediapipe:tasks-vision:1.0.0' }- Minimal repro, following
HolisticLandmarkerHelper.ktfromexamples/holistic_landmarker/androidverbatim:val baseOptions = BaseOptions.builder() .setModelAssetPath("holistic_landmarker.task") .build() val options = HolisticLandmarker.HolisticLandmarkerOptions.builder() .setBaseOptions(baseOptions) .setRunningMode(RunningMode.LIVE_STREAM) .setResultListener { result, _ -> /* ... */ } .setErrorListener { /* ... */ } .build() val landmarker = HolisticLandmarker.createFromOptions(context, options) // <-- throws here - Crash reproduces immediately, every time, on every protobuf-javalite version listed above.
- Swapping to
implementation('com.google.mediapipe:tasks-vision:1.0.0') { exclude group: 'com.google.protobuf', module: 'protobuf-javalite' }+implementation 'com.google.protobuf:protobuf-java:3.25.5'(i.e. exactly whatexamples/holistic_landmarker/android/app/build.gradlein this repo does) fixes it — confirmed working live on-device (pose + face + hand landmarks render correctly).
Other info / Complete Logs
Full stack trace:
E AndroidRuntime: FATAL EXCEPTION: main
E AndroidRuntime: java.lang.NoSuchMethodError: No virtual method build()Lcom/google/protobuf/Any; in class Lcom/google/protobuf/Any$Builder; or its super classes (declaration of 'com.google.protobuf.Any$Builder' appears in base.apk)
E AndroidRuntime: at com.google.mediapipe.tasks.vision.holisticlandmarker.HolisticLandmarker$HolisticLandmarkerOptions.convertToAnyProto(HolisticLandmarker.java:620)
E AndroidRuntime: at com.google.mediapipe.tasks.core.TaskInfo.generateGraphConfig(TaskInfo.java:125)
E AndroidRuntime: at com.google.mediapipe.tasks.core.TaskRunner.create(TaskRunner.java:82)
E AndroidRuntime: at com.google.mediapipe.tasks.core.TaskRunner.create(TaskRunner.java:58)
E AndroidRuntime: at com.google.mediapipe.tasks.vision.holisticlandmarker.HolisticLandmarker.createFromOptions(HolisticLandmarker.java:250)Related issues that describe the same underlying full-vs-lite protobuf conflict class, for context:
- google/mediapipe#2456 (the historical, opposite-direction case for
solution-core) - firebase/firebase-android-sdk#5997, #6359
- protocolbuffers/protobuf#18127
Also worth noting: examples/holistic_landmarker/android/app/build.gradle in this repo already has the exclude+protobuf-java workaround, but with no comment explaining why it's required — worth documenting there so future readers don't assume it's removable boilerplate.
Happy to provide a minimal standalone Gradle project reproducing this if useful.
Source: google-ai-edge/mediapipe