Java 8服务部署到DEV/QA环境后无法读取resources下services目录文件
问题排查与解决方案
核心问题分析
本地运行正常但部署后返回空列表,核心原因是部署后资源被打包在JAR文件内,而Files.list(Paths.get(dirName))仅能访问文件系统中的真实目录,无法读取JAR包内部的目录内容。以下是具体排查点和修复方案:
排查步骤
修正资源路径拼写错误
你的目标目录是resources/services,但获取路径的代码中写的是getResource("service")(缺少末尾的s),这会导致路径指向错误。先修正为:Thread.currentThread().getContextClassLoader().getResource("services").getPath()确认部署环境的资源完整性
- 解压DEV/QA环境中部署的JAR包,检查
services目录及内部.js文件是否存在。 - 路径中的
.cache是OSGi的缓存目录,仅用于存储解压后的JAR内容,不会直接导致文件无法读取,无需针对此文件夹做特殊处理。 - 读写权限并非核心问题:JAR内的资源是只读的,
Files.list仅需读权限,且你已配置权限,因此权限问题可以排除。
- 解压DEV/QA环境中部署的JAR包,检查
修复方案:正确读取JAR内的资源目录
替换当前的文件读取逻辑,改用Java原生API处理JAR内的资源:
通用Java 8实现
public List<String> getFilesFromDirectory(String dirName) throws IOException { List<String> fileNames = new ArrayList<>(); URL resourceUrl = Thread.currentThread().getContextClassLoader().getResource(dirName); if (resourceUrl == null) { return fileNames; } // 处理JAR包内的资源 if ("jar".equals(resourceUrl.getProtocol())) { // 解析JAR文件路径和内部目录 String jarPath = resourceUrl.getPath().substring(5, resourceUrl.getPath().indexOf("!")); try (JarFile jarFile = new JarFile(URLDecoder.decode(jarPath, "UTF-8"))) { Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String entryName = entry.getName(); // 匹配目标目录下的文件,排除子目录 if (entryName.startsWith(dirName + "/") && !entry.isDirectory()) { fileNames.add(entryName.substring(entryName.lastIndexOf("/") + 1)); } } } } // 兼容本地开发时的文件系统路径 else if ("file".equals(resourceUrl.getProtocol())) { Path dirPath = Paths.get(resourceUrl.toURI()); try (Stream<Path> pathStream = Files.list(dirPath)) { fileNames = pathStream.filter(Files::isRegularFile) .map(Path::getFileName) .map(Path::toString) .collect(Collectors.toList()); } } return fileNames; }
额外优化(若使用Spring框架)
如果你的项目基于Spring,可以用ResourcePatternResolver简化读取逻辑:
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resources = resolver.getResources("classpath:services/*.js"); List<String> fileNames = Arrays.stream(resources) .map(resource -> { try { return resource.getFilename(); } catch (IOException e) { return null; } }) .filter(Objects::nonNull) .collect(Collectors.toList());
内容的提问来源于stack exchange,提问作者EliasM
相关产品推荐
相关产品推荐

