-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
fix: Do not use default maven repo and stop propagating deps #11614
Conversation
c8d67eb
to
c5329bb
Compare
c5329bb
to
81a7a8e
Compare
use_repo(maven, maven = MAVEN_REPO) | ||
|
||
|
||
IO_GRPC_GRPC_JAVA_ARTIFACTS = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably no need for such long list.
I can look over this more, but this seems very wrong. There's no way it can work if all dependencies aren't merged together. The linked comment mostly talks about dependencies for rules, not runtime-time dependencies. All the dependencies involved here are runtime dependencies. As the comment says:
The change to Protobuf is mostly okay, as it is used for tests (still opens the door to test problems as duplicates can show up in the class path, but it doesn't impact you). And the main protobuf library doesn't have dependencies. But protobuf-util is broken. It can't use |
gRPC is quite different in this respect to Protobuf, as we don't have any tests running with Bazel. So all the dependencies are transitive dependencies, shy a rare neverlink=True dependency. |
I understand the concern and I hope this work could make sharing a maven repo usable, which as it is today is very much not the case. |
@honnix, in what way is it broken today? The useless "Found duplicate artifact versions" warning? |
Yeah that's one of them, and that might not be just a warning if users set the level to Besides the warning, this approach forces users of grpc-java to always use the default maven repo ( |
If that happens then either a) the user is using an older version and it is being upgraded (and they could upgrade the version the specify) or b) the user is using a newer version. For (b), the only available solution I've seen with Bazel will produce the warning. And neverlink is not a solution as it breaks transitive dependencies. The warning has always struck me as bizarre. It warns you when it is doing its job, which is to select the proper version. It has to do that already with transitive dependencies.
Really? If someone doesn't use the default name, then that's the same as if gRPC used a different name.
So you want to purposefully break the common case (gRPC deps must be runtime) for a theoretical case? Do you think everyone should standardize on a non-default name like "maven_runtime" just to avoid the default? I think the problem is that the warning is a warning, and |
Let's park the warning vs error question, since it is not critical.
Yeah, that is exactly the problem I mentioned in the PR description: the dependencies are forced into user space, regardless. In old WORKSPACE setup, dependencies are declared but not forced, which means users could choose to take the dep list as is, or skip it and maintain their own to only include deps they need, and they could choose which maven repo to install them to. To me, it worked more like
It's not theoretical as I explained, but more like resembling how grpc-java
Very good question and I guess it depends on use cases and also largely depends on how RJE could evolve. For pure internal/dev deps, they should absolutely be isolated in a non-default maven repo; for user facing deps, it should be clearly stated that the default maven repo must be used on user side (and this must be a standard followed by all modules because if anyone breaks it, there will likely be a classpath pollution). I hope RJE could come up with a better semantics. |
We do not support that. We don't support downgrades and we can add/change dependencies between versions. That is asking for bugs when upgrading (java.lang.Errors only found at runtime!).
Which we aren't using/supporting.
Because java_grpc_library both generates the code and creates the java_library, there's no way for the user to specify their own deps. And even if there was, that wouldn't work for transitive dependencies (java_proto_library in dependency Bazel repositories).
No. Maven and Gradle handle transitive deps. Maven does do it in a broken way that trivially downgrades dependencies, but we tell all users to use
I agree with that. Although Java testing deps will probably need to leak through, because the upstream project you depend on needs to avoid multiple versions of deps in tests.
Pollution? There's no pollution. The worst that happens is you get a newer version at runtime. But you need that anyway, because downgrading dependencies is generally unsupported and fragile. If you don't use a particular dependency (the target that uses it isn't part of your binary), then you will pay a cost as its dependency chain is looked up in Maven Central. But it doesn't change your binary other than version bumps of deps you actually depend on. |
It could be upgrade. For example, users may choose to use a later version of Guava, instead of the one introduced by grpc-java.
I meant the protoc compiler and grpc-java plugin do not introduce deps to user space, but for sure that is due to pure code generation than compiling, and I agree it works differently in the bazel rule.
It's actually pretty bad. Let me give an example. Suppose I have project depending on bazel module A and B, where A defines a maven repo I'm fine if this is not a supported case and I can patch the rule, but what I want to bring to the table is that, the way RJE module works is not great and it requires in depth knowledge for users to use it correctly. |
That can be done without issue using the shared
Not directly. But both require using a runtime that is at least as new as the generator. (protoc X is only supported with protobuf-java X or later.) There is a dependency, even if it is less typical. (This would still work fine if we used
If they are completely incompatible then they should have different Maven names and java packages (e.g., junit 4 vs junit 5 don't have the same name in Maven Central).
... you seem to be arguing my point. You need a single resolution of dependencies, otherwise you'll get duplicates. All deps going into a classpath need to use a single maven repo. And note this is even worse if Now it is certainly a problem if foo-1.0 and foo-2.0 are completely incompatible and have the same name in Maven. But that's a problem no matter what; you can't combine them together no matter what. If foo-2.0 is at least partly compatible with foo-1.0, then the resolution will pick 2.0 and that's the best anyone can do. |
Fair enough. I think we can park here and see how RJE iterates. Thank you for the great discussion. BTW there is another thing I want to mention, these overrides forces users of |
The protobuf overrides are needed "Because java_proto_library uses It's basically the same for the gRPC targets: java_grpc_library uses "" which has a runtime dependency on I've been mostly following Bazel's lead for protobuf because even if it has problems, doing my own thing just adds more problems. We could have |
Do you mean |
No, I meant the toolchain. It is an alias to |
neverlink=True
effectively stops propagating compile time dependencies to runtime (see When importing GRPC Java on bzlmod, we cannot control which version of guava is imported #11102). In non-bzlmod setup, the dependencies are declared but not implicitly propagated to user repo; however now in bzlmod setup, these dependencies will be introduced to user repo and that could result in classpath pollution (e.g. guava jre vs android). Asking users to use the same maven repo as grpc-java is not ideal, because it seems to be discouraged to share maven repo across modules; also version duplication could failduplicate_version_warning = error
that is often used by users to make sure nothing is duplicated in their dependency tree.Note that this is a breaking change because users now need to pull in those deps to their
java_library
,java_binary
, etc.A similar change happened in protobuf recently: protocolbuffers/protobuf#18641