
Fixing Dependency Metadata in Gradle
Hi! 👋 Today I’d like to share a story about discovering an interesting niche Gradle API that allows modifying metadata of dependencies published to a maven repo, for example.
The Problem
Recently I was tasked with adding Airbnb’s Showkase to our project. It was kind of easy, but when testing the app in other build types, I encountered a build error:
And so the research started …
Build Types
In the app, we have declared two custom build types: alpha
and beta
in addition to two default ones: debug
and release
. It looks like this:
The app successfully compiled only in debug
and release
. So seems like Showkase doesn’t support custom build types. There is a corresponding issue on GitHub. But I had no time to wait for the fix, so I needed a solution.
The Cause
To understand the root of the problem, we need some background on how Gradle deals with dependencies.
Android Dependency’s Metadata
When an Android library is published to a remote maven repository (e.g. MavenCentral), in addition to .aar
files, the Gradle Metadata file is published. It looks like this:
Today we will focus on variants and attributes.
Attributes
Some libraries declare special attributes on their versions. In Showkase’s case (no pun intended), two groups of versions were declared (as opposed to LeakCanary’s metadata file):
- Debug:
debugVariantMavenApiPublication
debugVariantMavenRuntimePublication
debugVariantMavenSourcePublication
debugVariantMavenJavaDocPublication
- Release
releaseVariantMavenApiPublication
releaseVariantMavenRuntimePublication
releaseVariantMavenSourcePublication
releaseVariantMavenJavaDocPublication
And each of the versions declared an attribute:
This is the cause of the problem. You see, Gradle has a special algorithm called variant aware matching (AGP has it too), that chooses a variant that will be used to build an app by matching attribute values, requested by the AGP with the above-mentioned list of variants.
In our case, the app needs an attribute BuildTypeAttr
to have the value alpha
, but Showkase’s metadata provides only variants with debug
and release
values.
If there are no matching variants, the following error occurs:
Execution failed for task ':app:mergeAlphaAssets'.
> Could not resolve all files for configuration ':app:alphaRuntimeClasspath'.
> Could not resolve com.airbnb.android:showkase:1.0.0-beta14.
Required by:
project :app > project :5d-android-sdk:community > project :5d-android-sdk:design-system
> No matching variant of com.airbnb.android:showkase:1.0.0-beta14 was found. The consumer was configured to find a runtime of a component, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'alpha', attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.3.1', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but:
- Variant 'debugVariantMavenApiPublication' capability com.airbnb.android:showkase:1.0.0-beta14:
- Incompatible because this component declares an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug' and the consumer needed a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'alpha'
- Other compatible attributes:
- Doesn't say anything about com.android.build.api.attributes.AgpVersionAttr (required '7.3.1')
- Doesn't say anything about its target Java environment (preferred optimized for Android)
- Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'androidJvm')
- Variant 'debugVariantMavenJavaDocPublication' capability com.airbnb.android:showkase:1.0.0-beta14 declares a runtime of a component:
- Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'alpha'
- Other compatible attributes:
- Doesn't say anything about com.android.build.api.attributes.AgpVersionAttr (required '7.3.1')
- Doesn't say anything about its target Java environment (preferred optimized for Android)
- Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'androidJvm')
- Variant 'debugVariantMavenRuntimePublication' capability com.airbnb.android:showkase:1.0.0-beta14 declares a runtime of a component:
- Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'alpha'
- Other compatible attributes:
- Doesn't say anything about com.android.build.api.attributes.AgpVersionAttr (required '7.3.1')
- Doesn't say anything about its target Java environment (preferred optimized for Android)
- Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'androidJvm')
- Variant 'debugVariantMavenSourcePublication' capability com.airbnb.android:showkase:1.0.0-beta14 declares a runtime of a component:
- Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'alpha'
- Other compatible attributes:
- Doesn't say anything about com.android.build.api.attributes.AgpVersionAttr (required '7.3.1')
- Doesn't say anything about its target Java environment (preferred optimized for Android)
- Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'androidJvm')
- Variant 'releaseVariantMavenApiPublication' capability com.airbnb.android:showkase:1.0.0-beta14:
- Incompatible because this component declares an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'alpha'
- Other compatible attributes:
- Doesn't say anything about com.android.build.api.attributes.AgpVersionAttr (required '7.3.1')
- Doesn't say anything about its target Java environment (preferred optimized for Android)
- Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'androidJvm')
- Variant 'releaseVariantMavenJavaDocPublication' capability com.airbnb.android:showkase:1.0.0-beta14 declares a runtime of a component:
- Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'alpha'
- Other compatible attributes:
- Doesn't say anything about com.android.build.api.attributes.AgpVersionAttr (required '7.3.1')
- Doesn't say anything about its target Java environment (preferred optimized for Android)
- Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'androidJvm')
- Variant 'releaseVariantMavenRuntimePublication' capability com.airbnb.android:showkase:1.0.0-beta14 declares a runtime of a component:
- Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'alpha'
- Other compatible attributes:
- Doesn't say anything about com.android.build.api.attributes.AgpVersionAttr (required '7.3.1')
- Doesn't say anything about its target Java environment (preferred optimized for Android)
- Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'androidJvm')
- Variant 'releaseVariantMavenSourcePublication' capability com.airbnb.android:showkase:1.0.0-beta14 declares a runtime of a component:
- Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'alpha'
- Other compatible attributes:
- Doesn't say anything about com.android.build.api.attributes.AgpVersionAttr (required '7.3.1')
- Doesn't say anything about its target Java environment (preferred optimized for Android)
- Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'androidJvm')
The Solution
The Easy Way
After a lot of googling, I found this article. It suggests doing this:
Using this field, you:
provide matching fallbacks for instances where a direct match is not possible
to the AGP.
That’s it, right? Well, in my case, there was a catch.
The Catch 😭

It turns out, that in a project structure similar to this, you need (not entirely sure why) to specify matchingFallbacks
in all build.gradle
files. I did this using a root file that we apply to all modules in the project.
Unfortunately, I haven’t realized that need in time, so I went
The Hard Way
We need to somehow modify that metadata JSON file and either:
- Add additional variants for each of our build types
- Remove an attribute from existing variants
The second option is not possible, because then there will be multiple matching versions, and Gradle will spill out an error.
Metadata Rules
Gradle has an API precisely for that task: Component metadata rules.
In short, we need to declare a class like that:
And then, we can use Showkase in our modules:
Source code of the whole solution:
And….
The build works!! 🎉
That’s all for today, I hope it helps! Feel free to leave a comment if something is not clear or if you have questions. Thank you for reading!