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

Docker容器内访问classpath资源抛出FileSystemNotFoundException问题

问题根源

核心原因是不同环境下classpath资源的存储形式不同,Paths.get()无法直接解析Jar包内部的资源URI:

  • 本地运行时,项目未打包成Jar,schemas目录是操作系统文件系统上的真实目录,返回的资源URI是标准file:协议,Paths.get()可以直接识别并解析为磁盘路径,所以运行正常。
  • Docker环境运行时,依赖的mylibrary库已经是Jar包形式,schemas目录存放在Jar包内部,返回的资源URI为jar:file:协议,路径里的!是Jar资源分隔符,代表!后的路径是Jar包内部的虚拟路径,JVM默认没有为jar协议注册对应文件系统实现,直接调用Paths.get()就会抛出FileSystemNotFoundException或FileNotFoundException。

你之前使用FileSystem.getDefault()只能获取操作系统默认的本地文件系统,只能处理Jar包外的真实磁盘路径,自然无法覆盖Jar内资源的场景,所以只能临时解决部分问题。

可行解决方法

由于你需要将合法路径传给第三方schema校验库使用,可根据校验库的支持情况选择以下方案:

方案1:资源拷贝到临时目录(兼容性最高)

如果校验库只支持读取本地磁盘路径,可将Jar包内的schemas目录整体拷贝到系统临时目录,再将临时目录路径传给校验库:

// 创建临时目录
Path tempSchemaDir = Files.createTempDirectory("runtime_schemas");
// 遍历schemas下所有资源,逐个写入临时目录(这里以单个文件为例,目录需要递归遍历)
String schemaFileName = "xxx.schema";
try (InputStream in = getClass().getClassLoader().getResourceAsStream("schemas/" + schemaFileName)) {
    if (in == null) {
        throw new RuntimeException("找不到schema资源: " + schemaFileName);
    }
    Files.copy(in, tempSchemaDir.resolve(schemaFileName));
}
// 将tempSchemaDir的绝对路径传给校验库即可

方案2:初始化Jar文件系统(性能更高)

如果校验库支持Java NIO的自定义FileSystem路径,可以先为Jar包创建专属文件系统,再解析内部路径:

URL resource = getClass().getClassLoader().getResource("schemas");
URI uri = resource.toURI();
Path schemaPath = null;
FileSystem jarFs = null;
if ("jar".equals(uri.getScheme())) {
    // 提取Jar包本身的路径
    String jarUriStr = uri.getSchemeSpecificPart().split("!")[0];
    // 为Jar包创建文件系统
    jarFs = FileSystems.newFileSystem(URI.create(jarUriStr), Collections.emptyMap());
    // 解析Jar内部的schemas路径
    schemaPath = jarFs.getPath("/schemas");
} else {
    // 非Jar环境直接解析
    schemaPath = Paths.get(uri);
}
// 使用schemaPath传入校验库,使用完毕后关闭jarFs释放资源

内容的提问来源于stack exchange,提问作者Said Savci

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 01:36:03