-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
build: Add Bazel java_grpc_library rule #2975
Conversation
Thanks for your pull request. The automated tests will run as soon as one of the admins verifies this change is ok for us to run on our infrastructure. |
ok to test |
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.
I glanced over it and it looks good.
Two things:
- Tests for java_grpc_library would be great
- I think maven_jar might be better than copying java_import_external from the closure rules.
I can add some tests post-merge. |
BUILD
Outdated
@@ -0,0 +1,126 @@ | |||
package(default_visibility = ["//visibility:public"]) | |||
|
|||
cc_binary( |
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.
Consider moving these build targets into the directory that they reference. For example, this rule should probably go in a BUILD file under compiler/
BUILD
Outdated
java_library( | ||
name = "core", | ||
srcs = glob([ | ||
"core/src/main/java/**/*.java", |
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.
Please don't use super globs. We are trying to split up the core and core internal package, and this pulls it in. It also unnnessarily pulls in inprocess
and util
.
BUILD
Outdated
) | ||
|
||
java_library( | ||
name = "protobuf-nano", |
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.
Please be consistent with underscores and dashes for name rules. I think underscores are more common.
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.
In that case, if I move the BUILD file to protobuf-nano should I keep the target the same as the directory name, or still replace with underscores?
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.
underscores
@simonhorlick I'm a bit busy at the moment, so it may be a week before I can look at this closer. |
It looks like my change to the gradle output directory is causing the Windows Jenkins build to fail. Presumably because it can't find the test outputs any more. |
Code taken from PR: grpc/grpc-java#2975 Once this is merged into gRPC we can directly depend on gRPC. Change-Id: Ide77414276b4125e85dfa6f93725143e3149d8ec
Bazel third party dependencies are specified in repositories.bzl which gives the consumer the ability to opt-out of any dependencies they use directly in their own project. Fixes grpc#2756
In 98bee07 I renamed the output directory that gradle uses because it clashes with the BUILD files. Alternatively it seems Bazel supports naming build files BUILD.bazel, which might be a less invasive way of achieving the same thing. Let me know if you think that would be better. |
ctx.action( | ||
inputs = [ctx.executable._java_plugin] + srcs + includes, | ||
outputs = [srcdotjar], | ||
executable = ctx.executable._protoc, |
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.
When hacking this into bazel [1], I found that creating the action this way let's protoc crash on Windows. Instead, I am building the command line myself.
I am quite sure this is a bazel bug, but haven't had time to investigate yet.
[1] https://github.com/bazelbuild/bazel/blob/master/third_party/grpc/build_defs.bzl
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.
I don't want us to make the command line ourselves, as then we have to deal with more possibilities of escaping. I'd rather us figure out what's wrong with using executable on Windows. That can happen after the merging of this PR.
@simonhorlick, Hmm... The BUILD vs build/ is an interesting problem. We'll have a similar problem internally as we have pre-existing Blaze BUILD files and we'll probably want both of them around for a bit as we migrate to have one canonical set. I've started a conversation internally asking about Blaze vs Bazel behavior; depending on how the two differ I'll be able to provide a recommendation. |
@simonhorlick, I'm pretty sure I want to use BUILD.bazel for now. I think it will make life easier for us as we support Blaze internally and also be convenient during migrating to a single set of BUILD files (Blaze+Bazel). In the future we may actually swap to using BUILD, but that's still TBD. |
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.
This looks pretty good.
BUILD
Outdated
@@ -0,0 +1,11 @@ | |||
package(default_visibility = ["//visibility:public"]) |
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.
Please don't set the default visibility to public. It makes it far too easy to leak targets. I say this as someone who has been surprised multiple times to learn a target was public and then needed to clean it up. Yes, I know it'll be annoying now because everything is actually public, but once we start adding tests and using java_libraries it is asking for trouble.
BUILD
Outdated
package(default_visibility = ["//visibility:public"]) | ||
|
||
java_library( | ||
name = "grpc_java", |
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.
What is this target used for?
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.
I was using it just to reduce the number of deps in rules that use grpc-java. You can see an example here: https://github.com/simonhorlick/grpc-java-helloworld/blob/master/java/io/grpc/examples/helloworld/BUILD#L44
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.
We had one of these targets internally, and it caused problems, because tons got added to it. If it is just core+stub, that seems like it could be fine. But on the other hand, one vs two targets for deps isn't that bad. @carl-mastrangelo, thoughts?
actual = "@com_google_code_gson//jar", | ||
) | ||
|
||
def com_google_api_grpc_google_common_protos(): |
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.
Was there a tool that created this stuff or that can help maintain it?
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.
I made this manually, I'm not actually sure if there are tools available.
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.
This is very close now, in my mind. @buchgr, wanna take another look?
BUILD
Outdated
package(default_visibility = ["//visibility:public"]) | ||
|
||
java_library( | ||
name = "grpc_java", |
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.
We had one of these targets internally, and it caused problems, because tons got added to it. If it is just core+stub, that seems like it could be fine. But on the other hand, one vs two targets for deps isn't that bad. @carl-mastrangelo, thoughts?
BUILD
Outdated
exports = [ | ||
"//core", | ||
"//stub", | ||
"@com_google_code_findbugs_jsr305//jar", |
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.
Remove export of jsr305 and guava.
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.
I would strongly prefer leaving the meta target out for now. It's something we can easily add in later.
There are a couple reasons for this:
- Right now auto generated build files and tools that auto add deps have a hard time figuring out what to do when a file is exposed through multiple targets. I think that making life easier for tools is a better long term strategy than making life easier for humans. (the former is a better deal for the latter).
- Bazel is not currently smart enough to trim deps not actually needed. For example, IIRC
core
depends on the Census library. Even if users really only neededstub
, they would pull in Census too (I realize that stub depends on core, but that's a much easier thing to fix). Same with the auth library, which depends on Google client libraries. (this had the sad effect of pulling in additional licences for hundreds of Android apps that are infeasible to back out, despite none of them actually needing it) - Bazel cannot figure out which deps are needed for compilation. It knows if they are missing, but it cannot decide if they happened to be unnecessary. This bloats jars. There have been at least 5 or 6 tools internally that try to find unnecessary deps, but in practice they each failed on a different set of corner cases, and have a pretty high rate of being ignored.
The temptation is strong to put everything in the grpc_java
, especially for new deps. (this happened for grpc's predecessor, and led to no jar being smaller than 200MB.) Let's stay lean and mean for now, and add this target back in once there is strong evidence that it would be widely useful.
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.
Thanks for the explanation, that makes a lot of sense.
core/BUILD.bazel
Outdated
name = "internal", | ||
srcs = glob([ | ||
"src/main/java/io/grpc/internal/*.java", | ||
]), | ||
visibility = ["//visibility:public"], |
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.
It seems this should have reduced visibility. I guess everything in grpc-java can use it, though? I guess I don't know how cross-repo visibility works in Bazel...
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.
I updated this to visibility = ["//:__subpackages__"]
and then tested it by depending on this target from another repo, bazel throws a visibility error as expected.
okhttp/BUILD.bazel
Outdated
"src/main/java/**/*.java", | ||
]), | ||
resources = glob([ | ||
"src/main/resources/**/*", |
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.
/**
should be sufficient no?
|
||
def com_google_api_grpc_google_common_protos(): | ||
native.maven_jar( | ||
name = "com_google_api_grpc_google_common_protos", |
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.
please sort args, or at least make arg order consistent across this and the the rules below. (e.g. sha1 comes after name)
Bazel requires an empty BUILD file here so users can reference //:repositories.bzl and //:java_grpc_library.bzl.
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.
Let's give @buchgr a day to mention whether he wants to take more of a look. If still no response, any issues can be cleaned up later. (I say this also because I spoke with him in person before my review and he sounded favorable toward the approaches that I knew nothing about.)
Of the two issues raised, I said I'd handle one later and the other seems resolved.
All comments appear addressed. Merging. |
Great, thanks for the reviews! |
Sorry, I was on a two week vacation, with mostly no internet :(. I am excited that this go merged! Thanks @simonhorlick ! |
CC @cgrushko. It's been a couple weeks, and it seems the Bazel build is working well. |
Bazel third party dependencies are specified in repositories.bzl which
gives the consumer the ability to opt-out of any dependencies they use
directly in their own project. Also note that reposititories.bzl
uses java_import_external from rules_closure instead of Bazel's built in
maven_jar. This allows us to specify multiple urls for each jar,
reducing the likelyhood of build failures due to repositories becoming
unavailable and also define dependencies between libraries.
Fixes #2756
References: bazelbuild/bazel#1952