Bazel Java测试无法访问data块指定文件的问题排查
解决Bazel Java测试中资源文件找不到的问题
核心问题
你遗漏了工作区名称在runfiles路径中的部分。Bazel会将data依赖的文件放在RUNFILES_DIR/<你的工作区名称>/<原始文件路径>下,直接使用resources/...或RUNFILES_DIR/resources/...都会找不到文件。
解决方案一:正确通过Runfiles访问Data依赖
- 确定工作区名称:即BUILD.bazel所在目录的名称,或WORKSPACE文件中
workspace(name = "...")定义的名称。 - 构造正确路径:
String runfilesDir = System.getenv("RUNFILES_DIR"); String filePath = runfilesDir + "/<你的工作区名称>/resources/inputs/my/pkg/ISimple.java"; File file = new File(filePath); - 更可靠的方式:使用Bazel Runfiles类
避免硬编码工作区名称,先在BUILD文件中添加依赖:
然后在测试代码中获取路径:java_test( name = "Simple", ... deps = [ ":allTests", "@bazel_tools//tools/java/runfiles:runfiles", ... ] )import com.google.devtools.build.runfiles.Runfiles; public class BasicTests { public void testResourceAccess() throws Exception { Runfiles runfiles = Runfiles.create(); String filePath = runfiles.rlocation("<你的工作区名称>/resources/inputs/my/pkg/ISimple.java"); File resourceFile = new File(filePath); // 后续操作 } }
解决方案二:将资源打包进测试Jar(推荐)
如果你最初的需求是把资源放入测试Jar,之前的FileSystemNotFoundException是因为错误地用File对象访问Jar内资源(Jar中的资源不是文件系统实体),正确做法如下:
- 修改BUILD文件,使用
resources属性:java_test( name = "Simple", srcs = [":test_sources"], test_class = "my.tests.BasicTests", resources = [":test_resources"], # 替换data为resources deps = [ ":allTests", ... ] ) - 通过类加载器读取资源:
public class BasicTests { public void testResourceAccess() throws Exception { // 路径以resources目录为根,即inputs/my/pkg/ISimple.java InputStream resourceStream = BasicTests.class.getClassLoader() .getResourceAsStream("inputs/my/pkg/ISimple.java"); // 使用流读取资源内容,不要用File对象 } }
补充说明
你之前用tree看到的resources/...是在执行Bazel命令的本地目录,但Bazel会在临时隔离目录中运行测试,测试进程的工作目录并非你本地项目目录,因此直接访问相对路径必然失败。
内容的提问来源于stack exchange,提问作者melston
相关产品推荐
相关产品推荐

