How to upgrade a Bazel-aware library's Maven dependency?

时间:2019-01-09 22:20:41

标签: bazel

My library supports Bazel builds and has a dependency from Maven Central. A user of my library wants to use a newer version of a dependency that has new transitive dependencies. How can that be done?

gRPC 1.17 depends on Guava 26. However, Guava 27 added a dependency on com.google.guava:failureaccess. Normally an application using gRPC would just make their own native.maven_jar() with the new version and disable gRPC's call to native.maven_jar(). This would then "upgrade" the @com_google_guava_guava repository that is then consumed by both gRPC and the application.

But @com_google_guava_guava does not include dependency information. That is commonly solved by having third_party java_library()s that stitch the transitive dependencies together. However, those java_library()s can't be changed by the application.

I believe that bind() would solve this problem, as gRPC could depend on //external:com_google_guava_guava which could be a java_library(). But bind() is discouraged.

3 个答案:

答案 0 :(得分:1)

考虑了一段时间之后,我觉得bind()可能是grpc-java提供此功能的最佳方法。我不知道现有的Maven转换工具中的任何功能可以简化此操作。

但是,如果用户希望在不更改grpc-java的情况下进行操作,则可以:

  1. WORKSPACE中,用com_google_guava_guava覆盖local_repository()

    grpc_java_repositories(
        omit_com_google_guava = True,
    )
    
    maven_jar(
        name = "com_google_guava_guava_real",
        artifact = "com.google.guava:guava:27.0.1-jre",
        sha1 = "bd41a290787b5301e63929676d792c507bbc00ae",
    )
    
    maven_jar(
        name = "com_google_guava_failureaccess",
        artifact = "com.google.guava:failureaccess:1.0.1",
        sha1 = "1dcf1de382a0bf95a3d8b0849546c88bac1292c9",
    )
    
    local_repository(
        name = "com_google_guava_guava",
        path = "guava_27",
    )
    
  2. 创建一个子仓库,该子仓库显示兼容的java_library()

    mkdir -p guava_27/jar
    echo > guava_27/WORKSPACE
    cat > guava_27/jar/BUILD.bazel << EOF
    java_library(
        name = "jar",
        visibility = ["//visibility:public"],
        exports = [
            "@com_google_guava_failureaccess//jar",
            "@com_google_guava_guava_real//jar",
        ],
    )
    EOF
    

答案 1 :(得分:1)

请考虑将您的库切换为使用java_import_external而不是maven_jar

java_import_external目标includes dependency information,因此允许应用程序取代目标的版本及其传递依赖项。

只需记住添加if native.existing_rule(name) == None: 在定义@com_google_guava_guava之前,以便允许您的库用户使用更新了依赖性的较新版本的番石榴自己定义它。

答案 2 :(得分:0)

更新:rules_jvm_external是Bazel团队的新规则集,用于可传递地获取和解决工件。

在这种情况下,WORKSPACE文件将包含以下内容:

load("@rules_jvm_external//:defs.bzl", "maven_install")

maven_install(
    artifacts = [
        "com.google.guava:guava:27.0.1-jre",
    ],
    repositories = [
        "https://jcenter.bintray.com",
    ]
)

这将自动解决并获取番石榴和failaccess工件。然后在BUILD文件中,您可以像这样直接依赖Guava:

java_library(
    name = "my_jar",
    srcs = # ...
    deps = [
        "@maven//com_google_guava_guava",
    ],
)