“exclude” attribute in jvm rules

23 views
Skip to first unread message

ittai zeidman

unread,
May 31, 2018, 11:44:58 PM5/31/18
to bazel-...@googlegroups.com, Dmitry Lomov
Hi folks,
We have a need to allow targets to exclude a target dependency from propagating downwards.
One example is that a binary wants to try out a new version of Jackson which is the same compile time but different runtime.
In maven they just override the “managed dependency” version in that module, run tests with the new version, deploy with the new version and evaluate.
In bazel one can define another maven_jar with a different name (for example with a version suffix) if they’re trying out an upgrade BUT they don’t have a way to exclude the label without the version in its name (the canonical name).
One solution I’ve thought about that can enable it is allowing a target to “exclude” dependencies so they are not propagated downstream. 
This of course can be misused but I think the deficiency we have now is so big the risk is worth it.

Wdyt?

Tom Lundell

unread,
May 31, 2018, 11:51:39 PM5/31/18
to ittai zeidman, bazel-...@googlegroups.com, Dmitry Lomov
I personally don't quite understand what you mean. Could you perhaps do a trivial strawman BUILD file example with some comments for clarity, pretending you already have some version of this capability? Thanks!

--
You received this message because you are subscribed to the Google Groups "Bazel/JVM Special Interest Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-sig-jv...@googlegroups.com.
To post to this group, send email to bazel-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-sig-jvm/CAOfK4wU3FXnr8kD86hdjJxx9GTBVrQ%2BM-oM%3Dog3vktb6X1ttbg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

ittai zeidman

unread,
Jun 1, 2018, 12:49:19 AM6/1/18
to Tom Lundell, bazel-...@googlegroups.com, Dmitry Lomov
Yes, I will do that.

ittai zeidman

unread,
Jun 2, 2018, 9:20:39 AM6/2/18
to Tom Lundell, bazel-...@googlegroups.com, Dmitry Lomov
java_library(
name = "uses_canonical_ver",
srcs = ["UsesCanonical.java"],
deps = ["//3rdparty/some_lib"]
)
#without exclude it's non deterministic what you'll get in runtime for `A.say`
java_library(
name = "uses_new_ver",
srcs = ["WantsToUseNewVer.java"],
deps = ["//3rdparty/some_lib/new_ver",":uses_canonical_ver"],
#exclude = ["//3rdparty/some_lib"]
)

Where A is a "third party" made up library with different runtime behavior.
new:
class A {
public static String say = "new";
canonical:
class A {
public static String say = "old";
}

Is it clearer?

Tom Lundell

unread,
Jun 2, 2018, 12:16:18 PM6/2/18
to ittai zeidman, bazel-...@googlegroups.com, Dmitry Lomov
So you want to evaluate a new lib right, maybe temporarily while doing a third party upgrade?

If so I'd recommend a select for this. I've used them in the past to simultaneously support multiple base SDK versions without having to use branches.

ittai zeidman

unread,
Jun 2, 2018, 1:34:37 PM6/2/18
to Tom Lundell, bazel-...@googlegroups.com, Dmitry Lomov
That’s the main use case I can think of right now.

Any chance for a small example of how you’d use select for this?

Thanks in advance!

Tom Lundell

unread,
Jun 2, 2018, 2:00:34 PM6/2/18
to ittai zeidman, bazel-...@googlegroups.com, Dmitry Lomov
The idea is to use a config_setting and switch on that using some configurable attribute. The below code isn't tested, but it's something like this.

config_setting(
    name = "use_lib_v2",
    values = {
        "define": "use-lib-v2",
    },
)

java_library(
  name = "foo",
  deps = [":lib"],
)

java_library(
  name = "lib",
  exports = select(
    ":use_lib_v2": [":lib_v2"],
    "//conditions:default": ["lib_v1"],
  ),
)

java_library(
  name = "lib_v1",
  ...
)

java_library(
  name = "lib_v2",
  ...
)

# Builds with v1
$ blaze build :foo

# Builds with v2
$ blaze build :foo --define=use-lib-v2

ittai zeidman

unread,
Jun 2, 2018, 2:12:33 PM6/2/18
to Tom Lundell, bazel-...@googlegroups.com, Dmitry Lomov
Awesome, thanks! 
Two small questions:
1. //conditions:default is a built in thing?
2. is there a way to enable this for only part of the workspace?
Context for #2 is that we might want to test out the new version on only one of the java_binary targets that the workspace has while still using the same `bazel build //...` command

Tom Lundell

unread,
Jun 2, 2018, 2:15:49 PM6/2/18
to ittai zeidman, bazel-...@googlegroups.com, Dmitry Lomov
On Sat, Jun 2, 2018 at 2:12 PM ittai zeidman <itt...@gmail.com> wrote:
Awesome, thanks! 
Two small questions:
1. //conditions:default is a built in thing?

Yes, kind of like //visibility:public.
 
2. is there a way to enable this for only part of the workspace?
Context for #2 is that we might want to test out the new version on only one of the java_binary targets that the workspace has while still using the same `bazel build //...` command

It isn't "enabled" in the workspace, you have to pass a command line argument to build for non-defaults.

Thus, you can try it on one, two, or three hundred java_binaries at once.

It's pretty powerful, because you can do thing like factor out srcs in your own libraries that are compatible with only one or the other SDK version, while sharing the 99% of the code that is.
Reply all
Reply to author
Forward
0 new messages