[gradle] Handle aggregating dependencies and relocation version conflicts (#1512)
This change improves the Gradle resolver's handling of two edge cases:
1. Aggregating dependencies with only classified artifacts:
Dependencies that exist solely to group platform-specific artifacts
(e.g., native libraries with -osx-aarch_64.jar but no base JAR) are
now correctly identified and collapsed.
2. Relocation version conflicts:
When a relocated artifact has a different version than requested,
the resolver now correctly handles this by preferring the target
artifact.
Key changes:
- Add collapseAggregatingDependencies() to handle deps with only
classified artifacts (sources, javadoc, platform-specific)
- Improve hasDownloadableArtifact() to check for actual non-POM files
- Handle relocation where target version differs from requested
- Add test for aggregating dependency resolution
Fixes issues where resolution would fail for native libraries or
produce incorrect graphs for relocated artifacts with version changes.
diff --git a/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleResolver.java b/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleResolver.java
index 8d928bb..b6eea23 100644
--- a/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleResolver.java
+++ b/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleResolver.java
@@ -275,7 +275,10 @@
}
// After building the graph, contract relocation stubs (keep aggregating POMs)
- collapseRelocations(graph, coordinateHashes, conflicts, artifactsByNode);
+ collapseRelocations(graph, coordinateHashes, conflicts, paths, artifactsByNode);
+
+ // Collapse aggregating dependencies (dependencies with only classified artifacts)
+ collapseAggregatingDependencies(graph, paths, artifactsByNode);
return new ResolutionResult(graph, conflicts, paths);
}
@@ -367,6 +370,7 @@
MutableGraph<Coordinates> graph,
Map<Coordinates, String> coordinateHashes,
Set<Conflict> conflicts,
+ Map<Coordinates, Path> paths,
Map<Coordinates, List<GradleResolvedArtifact>> artifactsByNode) {
List<Coordinates> toRemove = new ArrayList<>();
@@ -395,21 +399,40 @@
}
// Find the target node in the graph by matching G:A:V (ignore classifier/extension)
+ // If the exact version isn't found, look for any version of the same artifact
+ // since relocation means the artifact has moved regardless of version
Coordinates targetNode = null;
+ Coordinates targetNodeAnyVersion = null;
+
for (Coordinates candidate : graph.nodes()) {
if (candidate.getGroupId().equals(target.getGroupId())
- && candidate.getArtifactId().equals(target.getArtifactId())
- && candidate.getVersion().equals(target.getVersion())) {
- // Prefer non-POM node if possible
- if (targetNode == null) {
- targetNode = candidate;
- } else if (!"pom".equals(candidate.getExtension())
- && "pom".equals(targetNode.getExtension())) {
- targetNode = candidate;
+ && candidate.getArtifactId().equals(target.getArtifactId())) {
+
+ if (candidate.getVersion().equals(target.getVersion())) {
+ // Exact version match - prefer non-POM node if possible
+ if (targetNode == null) {
+ targetNode = candidate;
+ } else if (!"pom".equals(candidate.getExtension())
+ && "pom".equals(targetNode.getExtension())) {
+ targetNode = candidate;
+ }
+ } else {
+ // Different version - keep track in case we need it
+ if (targetNodeAnyVersion == null) {
+ targetNodeAnyVersion = candidate;
+ } else if (!"pom".equals(candidate.getExtension())
+ && "pom".equals(targetNodeAnyVersion.getExtension())) {
+ targetNodeAnyVersion = candidate;
+ }
}
}
}
+ // If exact version not found, use any version of the target artifact
+ if (targetNode == null) {
+ targetNode = targetNodeAnyVersion;
+ }
+
if (targetNode == null) {
// Could not find the relocation target in the graph; be conservative and skip
continue;
@@ -446,6 +469,7 @@
// Remove after iteration to avoid concurrent modification
for (Coordinates n : toRemove) {
graph.removeNode(n);
+ paths.remove(n);
}
}
@@ -479,6 +503,93 @@
return null;
}
+ private void collapseAggregatingDependencies(
+ MutableGraph<Coordinates> graph,
+ Map<Coordinates, Path> paths,
+ Map<Coordinates, List<GradleResolvedArtifact>> artifactsByNode) {
+ List<Coordinates> toRemove = new ArrayList<>();
+
+ for (Coordinates node : graph.nodes()) {
+ List<GradleResolvedArtifact> artifacts = artifactsByNode.get(node);
+ if (artifacts == null || artifacts.isEmpty()) {
+ continue;
+ }
+
+ // Check if this is an aggregating dependency:
+ // A dependency is aggregating if it has only POM files (no JAR/AAR artifacts)
+ // We check the actual filename since the extension field may not be reliable
+ boolean hasNonPomArtifact = false;
+
+ for (GradleResolvedArtifact artifact : artifacts) {
+ File file = artifact.getFile();
+ // Check the actual file name to see if it's a POM
+ if (file != null && !file.getName().endsWith(".pom")) {
+ hasNonPomArtifact = true;
+ break;
+ }
+ }
+
+ // If there are non-POM artifacts, this is not an aggregating dependency
+ if (hasNonPomArtifact) {
+ continue;
+ }
+
+ // This node only has POM artifacts. Check if it's an aggregating dependency.
+ // An aggregating dependency is one where:
+ // 1. It only has a POM file (checked above)
+ // 2. Either:
+ // a) Its successors are all classified variants of the SAME artifact, OR
+ // b) There exist other nodes in the graph with the same G:A:V but with classifiers
+ // (indicating this is a base coordinate for classified variants)
+ boolean isAggregating = false;
+ Set<Coordinates> successors = graph.successors(node);
+
+ if (!successors.isEmpty()) {
+ // Check if all successors are classified variants of this node
+ // (same group:artifact:version, but with classifiers)
+ boolean allSuccessorsAreClassifiedVariants = true;
+ for (Coordinates successor : successors) {
+ boolean isClassifiedVariant =
+ successor.getGroupId().equals(node.getGroupId())
+ && successor.getArtifactId().equals(node.getArtifactId())
+ && successor.getVersion().equals(node.getVersion())
+ && successor.getClassifier() != null
+ && !successor.getClassifier().isEmpty();
+
+ if (!isClassifiedVariant) {
+ allSuccessorsAreClassifiedVariants = false;
+ break;
+ }
+ }
+
+ isAggregating = allSuccessorsAreClassifiedVariants;
+ } else {
+ // No successors - check if there are classified variants in the graph
+ for (Coordinates other : graph.nodes()) {
+ if (other.getGroupId().equals(node.getGroupId())
+ && other.getArtifactId().equals(node.getArtifactId())
+ && other.getVersion().equals(node.getVersion())
+ && other.getClassifier() != null
+ && !other.getClassifier().isEmpty()) {
+ isAggregating = true;
+ break;
+ }
+ }
+ }
+
+ // Only remove if this is truly an aggregating dependency
+ if (isAggregating) {
+ toRemove.add(node);
+ }
+ }
+
+ // Remove aggregating base coordinates after iteration
+ for (Coordinates n : toRemove) {
+ graph.removeNode(n);
+ paths.remove(n);
+ }
+ }
+
private Repository createRepository(URI uri) {
Netrc.Credential credential = netrc.getCredential(uri.getHost());
if (credential == null) {
diff --git a/tests/com/github/bazelbuild/rules_jvm_external/resolver/ResolverTestBase.java b/tests/com/github/bazelbuild/rules_jvm_external/resolver/ResolverTestBase.java
index 6e9f318..3755835 100644
--- a/tests/com/github/bazelbuild/rules_jvm_external/resolver/ResolverTestBase.java
+++ b/tests/com/github/bazelbuild/rules_jvm_external/resolver/ResolverTestBase.java
@@ -748,6 +748,45 @@
assertEquals(Set.of(childA, childB), graph.successors(aggregator));
}
+ @Test
+ public void shouldHandleRelocationWithVersionConflict() {
+ // This test reproduces the mysql-connector-java issue where:
+ // - mysql:mysql-connector-java:8.0.33 is a relocation POM pointing to
+ // com.mysql:mysql-connector-j
+ // - When both the old coordinate (8.0.33) and new coordinate (8.4.0) are requested,
+ // - The resolver should handle the version conflict and pick the higher version
+
+ // The old artifact that has been relocated
+ Coordinates oldCoord = new Coordinates("mysql:mysql-connector-java:8.0.33");
+ // The new artifact at the same version as the relocation
+ Coordinates newCoordSameVersion = new Coordinates("com.mysql:mysql-connector-j:8.0.33");
+ // The new artifact at a higher version
+ Coordinates newCoordHigherVersion = new Coordinates("com.mysql:mysql-connector-j:8.4.0");
+
+ Path repo =
+ MavenRepo.create()
+ // Add the new coordinate at both versions
+ .add(newCoordSameVersion)
+ .add(newCoordHigherVersion)
+ // Add the relocation POM: old -> new (at same version)
+ .addRelocation(oldCoord, newCoordSameVersion)
+ .getPath();
+
+ // Request both the old coordinate and the new coordinate at different version
+ Graph<Coordinates> graph =
+ resolver
+ .resolve(prepareRequestFor(repo.toUri(), oldCoord, newCoordHigherVersion))
+ .getResolution();
+
+ // The resolver should:
+ // 1. Follow the relocation from mysql:mysql-connector-java:8.0.33 to
+ // com.mysql:mysql-connector-j:8.0.33
+ // 2. Resolve the version conflict between 8.0.33 and 8.4.0
+ // 3. Pick the higher version (8.4.0)
+ // The graph should only contain the higher version of the new coordinate
+ assertEquals(Set.of(newCoordHigherVersion), graph.nodes());
+ }
+
protected Model createModel(Coordinates coords) {
Model model = new Model();
model.setModelVersion("4.0.0");
diff --git a/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleResolverTest.java b/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleResolverTest.java
index 28f85d3..6460603 100644
--- a/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleResolverTest.java
+++ b/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleResolverTest.java
@@ -182,4 +182,69 @@
e.getCause().getMessage());
}
}
+
+ @Test
+ public void resolvesAggregatingDependencyWithOnlyClassifiedArtifacts()
+ throws IOException, XMLStreamException {
+ // This test validates that dependencies with only platform-specific classified artifacts
+ // (e.g., native libraries like netty-transport-native-kqueue with -osx-aarch_64.jar)
+ // are correctly marked as aggregating and resolution completes successfully
+ // without trying to download a non-existent base JAR.
+ Coordinates rootCoordinates = new Coordinates("com.example:app:1.0");
+ Coordinates nativeLibCoordinates = new Coordinates("com.example:native-lib:1.0");
+ MavenRepo mavenRepo = MavenRepo.create();
+ GradleModuleMetadataHelper moduleMetadataHelper = new GradleModuleMetadataHelper(mavenRepo);
+
+ Runfiles runfiles =
+ Runfiles.preload().withSourceRepository(AutoBazelRepository_GradleResolverTest.NAME);
+
+ // Add root artifact with dependency on native-lib
+ Path rootMetadataPath =
+ Paths.get(
+ runfiles.rlocation(
+ "rules_jvm_external/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/fixtures/aggregatingDependency/app-1.0.module"));
+ String rootMetadata = Files.readString(rootMetadataPath);
+ moduleMetadataHelper.addToMavenRepo(rootCoordinates, rootMetadata);
+
+ // Add native-lib with only classified artifacts (no base JAR)
+ // Use POM extension to avoid creating a base JAR file
+ Path nativeLibMetadataPath =
+ Paths.get(
+ runfiles.rlocation(
+ "rules_jvm_external/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/fixtures/aggregatingDependency/native-lib-1.0.module"));
+ String nativeLibMetadata = Files.readString(nativeLibMetadataPath);
+ Coordinates nativeLibPomCoordinates = nativeLibCoordinates.setExtension("pom");
+ moduleMetadataHelper.addToMavenRepo(nativeLibPomCoordinates, nativeLibMetadata);
+
+ // Add classified artifacts for native-lib
+ Coordinates osxAarch64 = new Coordinates("com.example:native-lib:jar:osx-aarch_64:1.0");
+ Coordinates osxX8664 = new Coordinates("com.example:native-lib:jar:osx-x86_64:1.0");
+ mavenRepo.add(osxAarch64);
+ mavenRepo.add(osxX8664);
+
+ // This should complete successfully without trying to download the base JAR
+ // (com.example:native-lib:1.0 without classifier)
+ var result = resolver.resolve(prepareRequestFor(mavenRepo.getPath().toUri(), rootCoordinates));
+ Graph<Coordinates> resolved = result.getResolution();
+
+ // Verify the graph contains the root coordinate
+ assertTrue(resolved.nodes().contains(rootCoordinates));
+
+ // The base coordinate for native-lib should NOT be in the graph
+ // because it only has a POM (it's an aggregating dependency with no base artifact)
+ assertEquals(
+ "Expected aggregating native-lib coordinate to be removed from graph",
+ false,
+ resolved.nodes().contains(nativeLibCoordinates));
+
+ // The classified artifacts should be in the graph
+ assertTrue(
+ "Expected osx-aarch_64 classified artifact in graph",
+ resolved.nodes().contains(osxAarch64));
+ assertTrue(
+ "Expected osx-x86_64 classified artifact in graph", resolved.nodes().contains(osxX8664));
+
+ // The graph should contain: app + 2 classified native-lib artifacts
+ assertEquals("Expected 3 coordinates in graph", 3, resolved.nodes().size());
+ }
}
diff --git a/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/fixtures/BUILD.bazel b/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/fixtures/BUILD.bazel
index e6b201f..5cacf15 100644
--- a/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/fixtures/BUILD.bazel
+++ b/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/fixtures/BUILD.bazel
@@ -1,6 +1,8 @@
filegroup(
name = "fixtures",
srcs = [
+ "aggregatingDependency/app-1.0.module",
+ "aggregatingDependency/native-lib-1.0.module",
"jvmAndAndroidVariants/sample-1.0.module",
"jvmAndAndroidVariants/sample-android-1.0.module",
"jvmAndAndroidVariants/sample-jvm-1.0.module",
diff --git a/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/fixtures/aggregatingDependency/app-1.0.module b/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/fixtures/aggregatingDependency/app-1.0.module
new file mode 100644
index 0000000..03952be
--- /dev/null
+++ b/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/fixtures/aggregatingDependency/app-1.0.module
@@ -0,0 +1,56 @@
+{
+ "formatVersion": "1.1",
+ "component": {
+ "group": "com.example",
+ "module": "app",
+ "version": "1.0",
+ "attributes": { "org.gradle.status": "release" }
+ },
+ "variants": [
+ {
+ "name": "runtimeElements",
+ "attributes": {
+ "org.gradle.category": "library",
+ "org.gradle.libraryelements": "jar",
+ "org.gradle.usage": "java-runtime"
+ },
+ "dependencies": [
+ {
+ "group": "com.example",
+ "module": "native-lib",
+ "version": { "requires": "1.0" },
+ "thirdPartyCompatibility": {
+ "artifactSelector": {
+ "name": "native-lib",
+ "type": "jar",
+ "extension": "jar",
+ "classifier": "osx-aarch_64"
+ }
+ }
+ },
+ {
+ "group": "com.example",
+ "module": "native-lib",
+ "version": { "requires": "1.0" },
+ "thirdPartyCompatibility": {
+ "artifactSelector": {
+ "name": "native-lib",
+ "type": "jar",
+ "extension": "jar",
+ "classifier": "osx-x86_64"
+ }
+ }
+ }
+ ],
+ "files": [
+ {
+ "name": "app-1.0.jar",
+ "url": "app-1.0.jar",
+ "size": 100,
+ "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
+ "md5": "d41d8cd98f00b204e9800998ecf8427e"
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/fixtures/aggregatingDependency/native-lib-1.0.module b/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/fixtures/aggregatingDependency/native-lib-1.0.module
new file mode 100644
index 0000000..0531b50
--- /dev/null
+++ b/tests/com/github/bazelbuild/rules_jvm_external/resolver/gradle/fixtures/aggregatingDependency/native-lib-1.0.module
@@ -0,0 +1,47 @@
+{
+ "formatVersion": "1.1",
+ "component": {
+ "group": "com.example",
+ "module": "native-lib",
+ "version": "1.0",
+ "attributes": { "org.gradle.status": "release" }
+ },
+ "variants": [
+ {
+ "name": "runtimeElements",
+ "attributes": {
+ "org.gradle.category": "library",
+ "org.gradle.libraryelements": "jar",
+ "org.gradle.usage": "java-runtime"
+ },
+ "dependencies": [
+ {
+ "group": "com.example",
+ "module": "native-lib",
+ "version": { "requires": "1.0" },
+ "thirdPartyCompatibility": {
+ "artifactSelector": {
+ "name": "native-lib",
+ "type": "jar",
+ "extension": "jar",
+ "classifier": "osx-aarch_64"
+ }
+ }
+ },
+ {
+ "group": "com.example",
+ "module": "native-lib",
+ "version": { "requires": "1.0" },
+ "thirdPartyCompatibility": {
+ "artifactSelector": {
+ "name": "native-lib",
+ "type": "jar",
+ "extension": "jar",
+ "classifier": "osx-x86_64"
+ }
+ }
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/custom_maven_install/regression_testing_gradle_index.json b/tests/custom_maven_install/regression_testing_gradle_index.json
index 6c4961a..c30925b 100644
--- a/tests/custom_maven_install/regression_testing_gradle_index.json
+++ b/tests/custom_maven_install/regression_testing_gradle_index.json
@@ -1,9 +1,6 @@
{
"__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
"packages": {
- "androidx.annotation:annotation-jvm": [
- "androidx.annotation"
- ],
"androidx.arch.core:core-common": [
"androidx.arch.core.internal",
"androidx.arch.core.util"
@@ -37,25 +34,6 @@
"com.google.guava:listenablefuture": [
"com.google.common.util.concurrent"
],
- "com.squareup.okhttp3:okhttp": [
- "okhttp3",
- "okhttp3.internal",
- "okhttp3.internal.authenticator",
- "okhttp3.internal.cache",
- "okhttp3.internal.cache2",
- "okhttp3.internal.concurrent",
- "okhttp3.internal.connection",
- "okhttp3.internal.http",
- "okhttp3.internal.http1",
- "okhttp3.internal.http2",
- "okhttp3.internal.io",
- "okhttp3.internal.platform",
- "okhttp3.internal.platform.android",
- "okhttp3.internal.proxy",
- "okhttp3.internal.publicsuffix",
- "okhttp3.internal.tls",
- "okhttp3.internal.ws"
- ],
"com.squareup.okio:okio-jvm": [
"okio",
"okio.internal"
@@ -136,6 +114,134 @@
]
},
"split_package_classes": {
+ "androidx.annotation:annotation": {
+ "androidx.annotation": [
+ "AnimRes",
+ "AnimatorRes",
+ "AnyRes",
+ "AnyThread",
+ "ArrayRes",
+ "AttrRes",
+ "BinderThread",
+ "BoolRes",
+ "CallSuper",
+ "CheckResult",
+ "ChecksSdkIntAtLeast",
+ "ColorInt",
+ "ColorLong",
+ "ColorRes",
+ "ContentView",
+ "DimenRes",
+ "Dimension",
+ "DoNotInline",
+ "DrawableRes",
+ "FloatRange",
+ "FontRes",
+ "FractionRes",
+ "GuardedBy",
+ "HalfFloat",
+ "IdRes",
+ "InspectableProperty",
+ "IntDef",
+ "IntRange",
+ "IntegerRes",
+ "InterpolatorRes",
+ "Keep",
+ "LayoutRes",
+ "LongDef",
+ "MainThread",
+ "MenuRes",
+ "NavigationRes",
+ "NonNull",
+ "Nullable",
+ "PluralsRes",
+ "Px",
+ "RawRes",
+ "RequiresApi",
+ "RequiresFeature",
+ "RequiresPermission",
+ "RestrictTo",
+ "Size",
+ "StringDef",
+ "StringRes",
+ "StyleRes",
+ "StyleableRes",
+ "TransitionRes",
+ "UiThread",
+ "VisibleForTesting",
+ "WorkerThread",
+ "XmlRes"
+ ]
+ },
+ "androidx.annotation:annotation-jvm": {
+ "androidx.annotation": [
+ "AnimRes",
+ "AnimatorRes",
+ "AnyRes",
+ "AnyThread",
+ "ArrayRes",
+ "AttrRes",
+ "BinderThread",
+ "BoolRes",
+ "CallSuper",
+ "CheckResult",
+ "ChecksSdkIntAtLeast",
+ "ColorInt",
+ "ColorLong",
+ "ColorRes",
+ "ContentView",
+ "DeprecatedSinceApi",
+ "DimenRes",
+ "Dimension",
+ "Discouraged",
+ "DisplayContext",
+ "DoNotInline",
+ "DrawableRes",
+ "EmptySuper",
+ "FloatRange",
+ "FontRes",
+ "FractionRes",
+ "GravityInt",
+ "GuardedBy",
+ "HalfFloat",
+ "IdRes",
+ "InspectableProperty",
+ "IntDef",
+ "IntRange",
+ "IntegerRes",
+ "InterpolatorRes",
+ "Keep",
+ "LayoutRes",
+ "LongDef",
+ "MainThread",
+ "MenuRes",
+ "NavigationRes",
+ "NonNull",
+ "NonUiContext",
+ "Nullable",
+ "OpenForTesting",
+ "PluralsRes",
+ "Px",
+ "RawRes",
+ "RequiresApi",
+ "RequiresExtension",
+ "RequiresFeature",
+ "RequiresPermission",
+ "RestrictTo",
+ "ReturnThis",
+ "Size",
+ "StringDef",
+ "StringRes",
+ "StyleRes",
+ "StyleableRes",
+ "TransitionRes",
+ "UiContext",
+ "UiThread",
+ "VisibleForTesting",
+ "WorkerThread",
+ "XmlRes"
+ ]
+ },
"androidx.collection:collection": {
"androidx.collection": [
"ArrayMap",
diff --git a/tests/custom_maven_install/regression_testing_gradle_install.json b/tests/custom_maven_install/regression_testing_gradle_install.json
index 0476c34..16a8c9a 100644
--- a/tests/custom_maven_install/regression_testing_gradle_install.json
+++ b/tests/custom_maven_install/regression_testing_gradle_install.json
@@ -1,11 +1,11 @@
{
"__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
"__INPUT_ARTIFACTS_HASH": 1541018928,
- "__RESOLVED_ARTIFACTS_HASH": 128343746,
+ "__RESOLVED_ARTIFACTS_HASH": 414364530,
"artifacts": {
"androidx.activity:activity-ktx:aar": {
"shasums": {
- "jar": "b0b4206ece92919925061fdf5784dd21f0118534609e8f6d9404bdd0f5cb5a3d"
+ "jar": "eeac7fea684727bfe1f339ee86ccca16518eafb24f02f1997dd7503911f40e63"
},
"version": "1.7.2"
},
@@ -17,7 +17,7 @@
},
"androidx.annotation:annotation": {
"shasums": {
- "jar": "fbc64f5c44a7added8b6eab517cf7d70555e25153bf5d44a6ed9b0e5312f7de9"
+ "jar": "9029262bddce116e6d02be499e4afdba21f24c239087b76b3b57d7e98b490a36"
},
"version": "1.6.0"
},
@@ -65,13 +65,13 @@
},
"androidx.compose.animation:animation-core:aar": {
"shasums": {
- "jar": "e1a44dc558d1966e3345f5c51f63afaaf2b5aeea20f478f026594363ae910675"
+ "jar": "53413f7e572f1410930826d63a027c73288ce4c1269591ebc503a56ba163f75b"
},
"version": "1.2.1"
},
"androidx.compose.foundation:foundation-layout": {
"shasums": {
- "jar": "f8cbd92d3585570dce2541aefef0d59b4c591ae225d98921058e484e9abf3e42"
+ "jar": "79af00811d834b966f383fb39454cff06e4a0045e5180eac5394d72fab9a1c97"
},
"version": "1.5.0-beta01"
},
@@ -239,13 +239,13 @@
},
"androidx.core:core:aar": {
"shasums": {
- "jar": "bc3f782e107b2d40cca9f0319d52e7343a0406e06febd42f9f2b509c3123438c"
+ "jar": "3c60213a2a2116a9314d3f4f9b6e7c32505353fa1143919bfb59366fef825151"
},
"version": "1.11.0-beta01"
},
"androidx.customview:customview-poolingcontainer:aar": {
"shasums": {
- "jar": "3584102fc49bf399c56e3b7be4bfe12000c46112320cd8cf85cc0a8f93f3e752"
+ "jar": "9fa62196c4c4e79b6a58dbb38a8c022bef8db21989d7dae2da0f6f5b66289a9c"
},
"version": "1.0.0"
},
@@ -257,13 +257,13 @@
},
"androidx.emoji2:emoji2:aar": {
"shasums": {
- "jar": "f31a06c150ecb03073f55a6f7b0b74a240a6a8d727c14ce76726d020570dfa8c"
+ "jar": "faf5955d2c9b09bba92e51569f2b928419ded05b5c9649c0453c925c7da62360"
},
"version": "1.2.0"
},
"androidx.fragment:fragment-ktx:aar": {
"shasums": {
- "jar": "3e4595cda9bee392715959366d70790704ff240c77656e702f3c8220b3d9245a"
+ "jar": "49222903181d392cece82b5146767d4c0b0c71287376befe6830ec64a01ca17d"
},
"version": "1.6.1"
},
@@ -323,7 +323,7 @@
},
"androidx.lifecycle:lifecycle-runtime:aar": {
"shasums": {
- "jar": "4867fd5279742fba8388821930cb2affe06d81a52814e7e41e70392ea0ef887c"
+ "jar": "41e71d003d437f169d4e8ada59cb1982f1b47b7d25c23010b8fc81d528a740d5"
},
"version": "2.6.1"
},
@@ -341,7 +341,7 @@
},
"androidx.lifecycle:lifecycle-viewmodel:aar": {
"shasums": {
- "jar": "e4ff4338999e1c6c9c724719f5d4aa7dd61bf6f545d5256a27a9d375df9f2330"
+ "jar": "dc2e8e65db53d21659a27ed93b966dee336c1c2e8e872861677389a99b8b9134"
},
"version": "2.6.1"
},
@@ -353,13 +353,13 @@
},
"androidx.profileinstaller:profileinstaller:aar": {
"shasums": {
- "jar": "34e8b2bfc74e23c1525e3da903ae449b7f1b440aef45e18159ee470e91997f48"
+ "jar": "12cbc01c8a5ae4b412caf3c5a0662ccd28002dedcff1dbe6c2ab3665be9f758c"
},
"version": "1.3.0"
},
"androidx.savedstate:savedstate-ktx:aar": {
"shasums": {
- "jar": "8553f87e7136c24ec5243560f48f1c32cba56daa77722f89589a5cafcb8f7894"
+ "jar": "d09553211f6703b19aefd608d6007c77132d27a281556a8e689d92764ec27d3b"
},
"version": "1.2.1"
},
@@ -401,7 +401,7 @@
},
"com.almworks.sqlite4java:libsqlite4java-linux-i386:so": {
"shasums": {
- "jar": "3c93ee3f997e957715fd08b263948d460da000a6e0bb904ae525e790f39429eb"
+ "jar": "85c80b7c2905db9edabbac0d58c738da3107ae7e09454448c700e157490558ad"
},
"version": "1.0.392"
},
@@ -419,7 +419,7 @@
},
"com.squareup.okhttp3:okhttp": {
"shasums": {
- "jar": "b1050081b14bb7a3a7e55a4d3ef01b5dcfabc453b4573a4fc019767191d5f4e0"
+ "jar": "7c737040a9419522e7c50cc027416a70fe7c7629e52b219935ade6b4119c7d38"
},
"version": "4.12.0"
},