-
-
Notifications
You must be signed in to change notification settings - Fork 273
Description
For some dependencies leveraging Gradle Module metadata, the resolver generates a lockfile fine but the maven tree has cycles. Consider the below example
maven.install(
name = "android_maven_deps",
artifacts = [
"androidx.appcompat:appcompat:1.6.1",
"androidx.constraintlayout:constraintlayout:2.1.4",
"androidx.navigation:navigation-fragment-ktx:2.6.0",
"androidx.navigation:navigation-ui-ktx:2.6.0",
"androidx.core:core:1.10.1",
"androidx.core:core-ktx:1.10.1",
"androidx.fragment:fragment-ktx:1.6.1",
"com.google.android.material:material:1.10.0",
"junit:junit:4.13.2",
"androidx.test.espresso:espresso-core:3.5.1",
],
lock_file = "//:maven_install.json",
repositories = [
"https://maven.google.com/",
"https://repo1.maven.org/maven2/",
],
resolver = "gradle",
)
Run REPIN=1 bazel run @android_maven_deps//:pin and then run bazel build @android_maven_deps//:all (or an android library that depends on some of the maven deps), you'll see a cycle like below.
ERROR: /private/var/tmp/_bazel_smocherla/9ba6fe3025d5a24a711a27211d7af8b6/external/rules_jvm_external++maven+my_maven/BUILD:1453:11: in aar_import rule @@rules_jvm_external++maven+my_maven//:androidx_savedstate_savedstate: cycle in dependency graph:
@@rules_jvm_external++maven+my_maven//:androidx_activity_activity (6c6c5c29ad6bd40b35919e8610f1eb023ea9183d35ae240db579717a51622940)
@@rules_jvm_external++maven+my_maven//:androidx_activity_activity (9b5881b1424f3fa4e1ca2fb75acbb41b00266413f4d1a59a4ba12bc51ace762b)
.-> @@rules_jvm_external++maven+my_maven//:androidx_savedstate_savedstate (9b5881b1424f3fa4e1ca2fb75acbb41b00266413f4d1a59a4ba12bc51ace762b)
| @@rules_jvm_external++maven+my_maven//:androidx_savedstate_savedstate_ktx (9b5881b1424f3fa4e1ca2fb75acbb41b00266413f4d1a59a4ba12bc51ace762b)
`-- @@rules_jvm_external++maven+my_maven//:androidx_savedstate_savedstate (9b5881b1424f3fa4e1ca2fb75acbb41b00266413f4d1a59a4ba12bc51ace762b)
Bazel doesn't like cycles for obvious reasons. And neither does gradle atleast in a single resolved graph in a configuration. So this one took some debugging but it appears to happen because of dependencyConstraints in the Gradle metadata of the artifacts. As gradle docs mention:
Dependency constraints function similarly to dependencies, with the key distinction that they do not introduce a dependency themselves
So because of this, the following code in the resolver
for (DependencyResult dep : component.getDependencies()) {
if (!(dep instanceof ResolvedDependencyResult)) {
continue;
}
ResolvedDependencyResult resolvedDep = (ResolvedDependencyResult) dep;
ResolvedComponentResult selected = resolvedDep.getSelected();
...
will also include dependency constraints as edges with getDependencies(). Why is that a problem? Consider the dependencies in the error above androidx.savedstate:savedstate and androidx.savedstate:savedstate-ktx. Both of them resolve to 1.2.1 in maven_install.json as seen below.
Now let's check the Gradle Metadata for both.
https://dl.google.com/android/maven2/androidx/savedstate/savedstate/1.2.1/savedstate-1.2.1.module (savedstate)
"dependencyConstraints": [
{
"group": "androidx.savedstate",
"module": "savedstate-ktx",
"version": {
"requires": "1.2.1"
}
}
],
The above introduces an edge from savedstate to savedstate-ktx
https://dl.google.com/android/maven2/androidx/savedstate/savedstate-ktx/1.2.1/savedstate-ktx-1.2.1.module (savedstate-ktx)
"dependencyConstraints": [
{
"group": "androidx.savedstate",
"module": "savedstate",
"version": {
"requires": "1.2.1"
}
}
],
The above introduces an edge from savedstate-ktx to savedstate.
Due to this, we now have the cycle seen in the bazel build. The only valid dependency is from savedstate-ktx to savedstate as seen from the dependencies section
"dependencies": [
{
"group": "androidx.savedstate",
"module": "savedstate",
"version": {
"requires": "1.2.1"
}
},
{
"group": "org.jetbrains.kotlin",
"module": "kotlin-stdlib",
"version": {
"requires": "1.8.10"
}
}
],
Gradle provides a way to detect if a resolved dependency is a dependency constraint and not an actual dependency with https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/result/DependencyResult.html#isConstraint() which we can use here to eliminate those edges.
Interestingly enough, gradle itself also handles this here https://github.com/gradle/gradle/blob/06bba06808c1d6bf5dd0157ec8ec30a58c877e27/platforms/software/software-diagnostics/src/main/java/org/gradle/api/tasks/diagnostics/internal/graph/DependencyGraphsRenderer.java#L100 when rendering dependencies and avoid going into cycles.
A similar cycle can be seen if you add androidx.fragment:fragment-ktx:1.6.1 here and regen the lockfile
maven_install(
name = "regression_testing_gradle",
artifacts = [
# https://github.com/bazel-contrib/rules_jvm_external/issues/909
"androidx.compose.foundation:foundation-layout:1.5.0-beta01",
# https://github.com/bazel-contrib/rules_jvm_external/issues/909#issuecomment-2019217013
"androidx.annotation:annotation:1.6.0",
# https://github.com/bazel-contrib/rules_jvm_external/issues/1409
"com.squareup.okhttp3:okhttp:4.12.0",
# https://github.com/bazel-contrib/rules_jvm_external/issues/1471
"androidx.fragment:fragment-ktx:1.6.1",
],
generate_compat_repositories = True,
maven_install_json = "//tests/custom_maven_install:regression_testing_gradle_install.json",
repin_instructions = "Please run `REPIN=1 bazel run @regression_testing_gradle//:pin` to refresh the lock file.",
repositories = [
"https://repo1.maven.org/maven2",
"https://maven.google.com",
],
resolver = "gradle",
)
and build
WARNING: errors encountered while analyzing target '@@_main~maven~regression_testing_gradle//:androidx_compose_ui_ui_util', it will not be built.
ERROR: /private/var/tmp/_bazel_smocherla/536b5c8af4e86fad57fc24f39380ac8a/external/_main~maven~regression_testing_gradle/BUILD:1850:11: in aar_import rule @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_viewmodel_savedstate: cycle in dependency graph:
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx_2_6_1 (47e801383873100ccaaef3b95ef65bfd34a90b019bca16b9564cbba636e352c6)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx (47e801383873100ccaaef3b95ef65bfd34a90b019bca16b9564cbba636e352c6)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_viewmodel_ktx (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
.-> @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_viewmodel_savedstate (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
| @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_viewmodel (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
`-- @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_viewmodel_savedstate (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
ERROR: /private/var/tmp/_bazel_smocherla/536b5c8af4e86fad57fc24f39380ac8a/external/_main~maven~regression_testing_gradle/BUILD:2051:11: in aar_import rule @@_main~maven~regression_testing_gradle//:androidx_savedstate_savedstate: cycle in dependency graph:
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx_2_6_1 (47e801383873100ccaaef3b95ef65bfd34a90b019bca16b9564cbba636e352c6)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx (47e801383873100ccaaef3b95ef65bfd34a90b019bca16b9564cbba636e352c6)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_viewmodel_ktx (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_viewmodel_savedstate (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
.-> @@_main~maven~regression_testing_gradle//:androidx_savedstate_savedstate (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
| @@_main~maven~regression_testing_gradle//:androidx_savedstate_savedstate_ktx (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
`-- @@_main~maven~regression_testing_gradle//:androidx_savedstate_savedstate (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
ERROR: /private/var/tmp/_bazel_smocherla/536b5c8af4e86fad57fc24f39380ac8a/external/_main~maven~regression_testing_gradle/BUILD:1797:11: in aar_import rule @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_viewmodel_ktx: cycle in dependency graph:
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx_2_6_1 (47e801383873100ccaaef3b95ef65bfd34a90b019bca16b9564cbba636e352c6)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx (47e801383873100ccaaef3b95ef65bfd34a90b019bca16b9564cbba636e352c6)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
.-> @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_viewmodel_ktx (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
| @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_viewmodel_savedstate (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
`-- @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_viewmodel_ktx (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
ERROR: /private/var/tmp/_bazel_smocherla/536b5c8af4e86fad57fc24f39380ac8a/external/_main~maven~regression_testing_gradle/BUILD:1741:11: in aar_import rule @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime: cycle in dependency graph:
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx_2_6_1 (47e801383873100ccaaef3b95ef65bfd34a90b019bca16b9564cbba636e352c6)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx (47e801383873100ccaaef3b95ef65bfd34a90b019bca16b9564cbba636e352c6)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
.-> @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
| @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_viewmodel_ktx (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
`-- @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
ERROR: /private/var/tmp/_bazel_smocherla/536b5c8af4e86fad57fc24f39380ac8a/external/_main~maven~regression_testing_gradle/BUILD:1687:11: in aar_import rule @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx: cycle in dependency graph:
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx_2_6_1 (47e801383873100ccaaef3b95ef65bfd34a90b019bca16b9564cbba636e352c6)
@@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx (47e801383873100ccaaef3b95ef65bfd34a90b019bca16b9564cbba636e352c6)
.-> @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
| @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
`-- @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx (d2ba34083d5d2b9afc911c8ef1260b5a22a4542c041360241fc8c3e4af3fea72)
ERROR: /private/var/tmp/_bazel_smocherla/536b5c8af4e86fad57fc24f39380ac8a/external/_main~maven~regression_testing_gradle/BUILD:1687:11: in aar_import rule @@_main~maven~regression_testing_gradle//:androidx_lifecycle_lifecycle_runtime_ktx: cycle in dependency graph:
with bazel build @regression_testing_gradle//:pin --keep_going