如何在Bazel中配置Java META-INF目录及services服务资源文件
Bazel 配置 Java SPI 实现的正确方式
资源文件存放位置
不要单独创建顶层resources目录,直接将SPI配置文件放在自定义System.LoggerFinder实现类所属的java_library包目录下,严格匹配JAR包内的资源路径结构:
- 在该
java_library对应的BUILD文件同级目录,创建META-INF/services/层级目录 - 将配置文件命名为
java.lang.System$LoggerFinder放入上述目录,文件内容填写自定义LoggerFinder实现类的全限定名即可
BUILD文件正确配置
直接在存放LoggerFinder实现的java_library规则中声明资源,不需要跨包引用资源,也不需要额外的resources前缀,参考配置:
java_library( name = "custom_logger_finder", srcs = glob(["src/**/*.java"]), # 替换为你实际的源码路径匹配规则 resources = glob(["META-INF/services/**"]), visibility = ["//visibility:public"], )
配置完成后,你现有的java_binary只需要保持对这个java_library的依赖即可,不需要在binary侧重复声明SPI资源,Bazel打包时会自动将同library下的资源合并入最终产物,符合SPI的加载路径要求。
之前报错的原因说明
- 相对路径找不到文件:你写的
resources/META-INF/...路径,Bazel默认从WORKSPACE根目录(即//对应的路径)查找文件,该路径下不存在对应文件就会抛出找不到的错误。 - 绝对路径提示缺BUILD文件:写
//resources/...时,Bazel会将resources识别为WORKSPACE下的独立Bazel包,包目录下必须存在BUILD文件才能被引用,单独建这个资源包对于当前场景完全多余。
特殊场景补充
如果确实需要将SPI资源和实现代码拆分到不同目录管理,才需要在资源目录下添加BUILD文件,使用filegroup规则导出资源文件,再在java_library中通过resource_deps字段引用该filegroup,常规场景下不推荐这么做,将SPI配置和对应实现放在同一个java_library是最稳妥、符合Java生态惯例的方案。
内容的提问来源于stack exchange,提问作者Jo Bo
相关产品推荐
相关产品推荐

