Comments (8)
@illicitonion Let me add our use case here as well.
We have two separate rules_jvm_external trees for SpringBoot 2 and SpringBoot 3. We didn't have the capacity to do a mass migration, so we allowed service owners to upgrade at their own pace. To make things more complicated, we also have some services using DropWizard 3 and they have their own tree coz their transitives are different from SB2 and SB3, but for the sake of presenting our use case (and for my sanity), let's just consider the SB2 and SB3 trees.
Some of the core libraries that we have written are shared between the SB2 and SB3 and the major difference between them is that the former uses the javax
namespace while the latter uses jakarta
namespace. The other major differences are the transitive dependencies. So, instead of forking the source code, what we did was create a Bazel rule that replaces javax
imports to jakarta
. So, a sample BUILD file would look like this:
java_library(
name = "my-core-lib",
deps = [
"@maven_sb2//:...",
...
],
)
java_library_jakarta(
name = "my-core-lib-jakarta",
deps = [
"@maven_sb3//:...",
...
],
)
Our current situation should go away as everything moves to SB3, but this could potentially be something that happens with another migration in the future. Having said that, the forking would have made this simpler, but forking a significant amount of libraries is also not trivial and is not easy to maintain during the transition period and this strategy helped us get going faster.
Something we don't do, like in @kriscfoster's case, is mix trees. We don't have the technology to deal with managing transitive across trees and I don't think that's something we'll explore either (although we do have the same conflict issues that they mentioned and I'll talk a bit about that later).
I imagine we'd do this on a sub-tree level, so you could specify that src1/... uses one maven_install, and src2/... uses another. I don't think we'd want to support it more granularly than that (e.g. per target, or per maven package).
We would like to have at least per target granularity or even be able to auto-detect which tree to use per target based on the dependencies it uses. Compiling the same source set with different deps + transitives seems like a potentially common use-case especially during transition periods.
Would love to hear your thoughts on this! I am open to hearing some process recommendations too as we are still at the early stages of managing a monorepo.
though it may be noting that the new lock file format in recent rules_jvm_external releases was specifically designed to reduce conflicts, so it may be worth investigating consolidating them back into a single default maven_install again.
@shs96c We are using the new lock format (and also trying out the new BOM resolver to see if things get easier), but as it is, it doesn't help a whole lot as the __INPUT_ARTIFACTS_HASH
and the __RESOLVED_ARTIFACTS_HASH
ALWAYS causes conflicts... We have Renovate updating the versions for us, but our dep trees are not comprehensive (at least yet), so it is common for developers to need to add new libraries / manually do upgrades when Renovate fails.
We have tried several things like moving Renovate MRs to run during off peak hours, but we still end up getting at least a couple of conflicts a day and is a major point of frustration for our developers.
Since it is a generated file, we end up choosing either version on git and re-run the repinning process, but that takes a significant amount of time as we have a large number of dependencies. And then it's back to the rat race to see who can get their changes in first and then it is back to conflicts for the next person...
We read up on Alex Eagle's Easier merges on lockfiles as well, but that doesn't really solve the problem that we are having. It is an easier way to solve the merge conflicts, but we still have to run the repinning process again.
Maybe we are doing something wrong here / not using things as intended and there might be some recommendations from your end that might help us out and would love to hear your thoughts!
from rules_jvm.
Aha - yeah, unfortunately that kind of support is probably not great to add - it'd be great to work with the rules_jvm_external maintainers to work out how to better support your use-cases - ideally rules_jvm_external would be ergonomic enough that you didn't feel the need to manually do that sharding... /cc @shs96c
from rules_jvm.
The typical usage pattern is that most repos declare one main maven_install
including all their dependencies, and break out separate maven_install
declarations for particularly troublesome libraries (some of the Apache Spark stuff springs to mind) which are used in tightly controlled areas of the repo.
The approach of stitching together multiple different maven_install
instances as @kriscfoster describes is very unusual (first I've heard of it), though it may be noting that the new lock file format in recent rules_jvm_external
releases was specifically designed to reduce conflicts, so it may be worth investigating consolidating them back into a single default maven_install
again.
from rules_jvm.
This seems pretty reasonable to support - I imagine we'd do this on a sub-tree level, so you could specify that src1/...
uses one maven_install, and src2/...
uses another. I don't think we'd want to support it more granularly than that (e.g. per target, or per maven package).
Currently, the maven resolver is a global property of a Configuration
:
rules_jvm/java/gazelle/configure.go
Lines 138 to 147 in fae67e4
To change this, I think we'd want to make it instead be a property of a Config
:
rules_jvm/java/gazelle/javaconfig/config.go
Lines 89 to 103 in fae67e4
We'd want to make it so that each config inherits its parent resolver (if NewChild
is called:
rules_jvm/java/gazelle/javaconfig/config.go
Lines 55 to 57 in fae67e4
java_maven_install_file
and/or java_maven_repository_name
directive is encountered (which... We may want to strictly require that both are set), we'll replace it with a new one here: rules_jvm/java/gazelle/configure.go
Line 100 in fae67e4
rules_jvm/java/gazelle/configure.go
Lines 113 to 114 in fae67e4
I'd be happy to review a PR adding this - there's an example integration test in https://github.com/bazel-contrib/rules_jvm/tree/main/java/gazelle/testdata/maven that could be cribbed from to add a test for this functionality.
from rules_jvm.
Thank you for the comment & pointers @illicitonion,
It is getting me thinking a little bit more about what this would look like.
Our usage is actually a little more complex/dynamic than different packages using different maven install rules. We bring in ~1000 external jars so we divide them logically into their own maven install rules (~5 -> ~70 jars in each) to minimise merge conflicts etc of the pinned JSON files. We have some tooling on-top of this to maintain single version of transitives etc but in the end it is just multiple maven_install
rules. For example, we might have an @org_eclipse
namespace for all org.eclipse
jars & an @org_apache
namespace for all org.apache
jars. That means a single java_library
target could also bring in jars from ~10 different maven install rules.
from rules_jvm.
rules_jvm_external
actually document having multiple maven_install.json files (https://github.com/bazelbuild/rules_jvm_external#multiple-maven_installjson-files) so it is probably something a lot of larger repos do. I'll take a look at the code you linked above anyway & think about it a little bit more.
from rules_jvm.
rules_jvm_external
actually document having multiple maven_install.json files (https://github.com/bazelbuild/rules_jvm_external#multiple-maven_installjson-files) so it is probably something a lot of larger repos do.
I think there's a strong assumption that they're used independently, though :)
from rules_jvm.
The typical usage pattern is that most repos declare one main
maven_install
including all their dependencies, and break out separatemaven_install
declarations for particularly troublesome libraries (some of the Apache Spark stuff springs to mind) which are used in tightly controlled areas of the repo.The approach of stitching together multiple different
maven_install
instances as @kriscfoster describes is very unusual (first I've heard of it), though it may be noting that the new lock file format in recentrules_jvm_external
releases was specifically designed to reduce conflicts, so it may be worth investigating consolidating them back into a single defaultmaven_install
again.
Thank you @shs96c, we didn't know about the new lock-file format. It may help us a little bit in this case!
from rules_jvm.
Related Issues (20)
- Discussion: what's the relationship between rules_jvm and rules_java? HOT 1
- Failed to find javaparser in runfiles HOT 16
- Fetching dependencies for JUnit5 runner tries to use local java HOT 1
- Allow setting SecurityManager
- Support exclusions in addition to test_suffixes in java_test_suite HOT 1
- Can't clone it in our windows kokoro jobs HOT 1
- Duplicate artifacts versions
- Checkstyle tests don't work with a generated checkstyle.xml HOT 2
- Cannot be used with `--override_repository`: cannot load '@@rules_java//java:repositories.bzl': no such file HOT 2
- Not able to download contrib_rules_jvm via bzlmod......failing to resolve transitive dependencies HOT 1
- No maven lockfile for bzlmod
- java_test_suite silently drops `data` HOT 2
- SpotBugs targets fail when we have more than one plugin in Unix-like systems
- Gazelle fails on Windows with "javaparser/generators/Main: file does not exist"
- Gazelle fails on Windows with "panic: runtime error: invalid memory address or nil pointer dereference"
- Gazelle fails on Windows with "java.nio.file.InvalidPathException: Illegal char <:> at index 2" HOT 1
- Run gazelle tests on CI on Windows
- srcs is updated with the OS-specific path separator
- Re-add tests for "missing maven_install.json leads to a useful warning" case
- Don't fail silently when running a junit4 test in junit5 test suite w/o vintage HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rules_jvm.