You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Bazel的java_binary规则中拆分_deploy.jar内的依赖与自有代码

最优Bazel侧实现方案

方案1:使用原生java_binary的deploy_env参数(零额外开发成本,最推荐)

Bazel原生java_binary规则内置的deploy_env参数正是为这种场景设计的:该参数指定的目标及其所有传递依赖,都不会被打包进最终的_deploy.jar产物中。

你只需要修改原有java_binary配置,增加一行deploy_env声明即可:

java_library(
  name = "mylib",
  srcs = ...,
  deps = ...
)

java_binary(
  name = "mybin",
  main_class = ...,
  runtime_deps = ["//:mylib"],
  # 新增这一行,指定mylib及其传递依赖不打入deploy jar
  deploy_env = ["//:mylib"],
)

修改后执行构建:

  • bazel build //:mybin_deploy.jar 得到的产物仅包含所有第三方依赖,无任何自有业务代码,大小约198.5MB
  • bazel build //:mylib 得到的libmylib.jar就是你的业务代码包,大小约1.5MB

Dockerfile可以直接简化,去掉额外的zip处理阶段:

FROM openjdk:18-slim-buster
WORKDIR /app
CMD ["java", "-cp", "/app/mybin_deps.jar:/app/mylib.jar", "com.Main"]
COPY mybin_deploy.jar /app/mybin_deps.jar
COPY libmylib.jar /app/mylib.jar

该方案完全复用Bazel原生能力,不需要任何自定义规则开发,也避免了手动修改jar包可能带来的文件损坏、路径匹配错误等问题。

方案2:使用rules_docker直接构建分层镜像(Docker集成更顺滑)

如果你需要直接用Bazel输出Docker镜像,可以使用官方的rules_docker规则集中的java_image规则,它会自动将第三方依赖、自有代码拆分为独立的镜像层,依赖未发生变化时,镜像推送只会上传1.5MB的业务代码层。

配置示例:

load("@io_bazel_rules_docker//java:image.bzl", "java_image")

java_image(
  name = "mybin_image",
  binary = ":mybin",
  main_class = "com.Main",
  base = "@openjdk_18_slim_buster//image",
)

直接执行bazel build //:mybin_image即可得到符合要求的分层镜像。

内容的提问来源于stack exchange,提问作者Matt McMinn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 06:24:01