Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bzlmod] Cross-module artifact resolution (single-version policy) #995

Open
SanjayVas opened this issue Nov 21, 2023 · 3 comments
Open

[bzlmod] Cross-module artifact resolution (single-version policy) #995

SanjayVas opened this issue Nov 21, 2023 · 3 comments

Comments

@SanjayVas
Copy link

SanjayVas commented Nov 21, 2023

Can some documentation be included on the right way to use the module extension when rules_jvm_external is used by multiple dependencies or by a dependency and the root module?

Example dependency graphs, where "->" indicates "depends on":

  1. B -> A
  2. C -> B -> A
  3. C -> A and C -> B

Supposing each of A, B, and C above use the module extension to include Maven artifacts. What is the right way to configure the modules such that they share Maven artifact resolution (i.e. if both A and B include some Maven artifact X we only get one copy/version of X)?

In WORKSPACE mode, we handle this by having each project expose its list of artifacts and only having the root WORKSPACE call maven_install.

@SanjayVas
Copy link
Author

Another way to phrase this would be "how to enforce a single-version policy for all Maven artifacts"

@SanjayVas SanjayVas changed the title bzlmod: Pattern for use in multiple dependencies [bzlmod] Cross-module artifact resolution (single-version policy) Nov 29, 2023
@SanjayVas
Copy link
Author

Concrete example of this causing build headaches yesterday:

  • A has a java_library target with a dep from Maven that transitively depends on com.google.guava:guava. Dependency resolution picked up the Android version since it wasn't explicitly specified.
  • B depends on that library target from A and also directly depends on com.google.guava:guava. It uses functions that aren't available in the Android version, so it explicitly specifies the jre version.

The only workaround I've found is to ensure that all of my projects that use rules_jvm_external use the same repo name in the Maven extension. This of course results in lots of warnings, and is also only possible if I don't end up with two module deps I don't control that use different names.

SanjayVas added a commit to world-federation-of-advertisers/rules_kotlin_jvm that referenced this issue Jan 18, 2024
This ensures a single version for library dependencies that come from Maven.

See bazelbuild/rules_jvm_external#1035 (comment) and bazelbuild/rules_jvm_external#995.
@shs96c
Copy link
Collaborator

shs96c commented Mar 1, 2024

The way to share artifacts is to use the same name attribute in the tags (eg. install and artifact). By default, this is set to maven, so you may not have a name attribute on any of your tags at the moment.

When run, we aggregate all the artifacts from tags with the same name (that is, module A can contribute to dependencies that module B can use). This is needed because MODULE.bazel files do not allow loading of constants, and so there's no other way to share which dependencies should be added. As you've noticed, we print a warning when we find the same name being used in multiple repos. This is done to facilitate debugging the "where did this dep come from?" issue.

For lock files, if the root module specifies a lock file, that is the one that is used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants