Java Cloud Run部署后无法读取resources文件夹下文件问题咨询
问题根因
- 本地执行
mvn clean spring-boot:run时,Maven直接读取源码目录下独立存放的resources文件,用文件系统路径访问可以正常生效 - 部署到Cloud Run时运行的是打包后的可执行jar包,resources目录下的所有文件都会被打入jar包内部的
BOOT-INF/classes/路径下,不属于操作系统独立文件系统的文件,所以你遍历系统根目录找不到对应文件 - application.properties能正常读取是因为Spring Boot原生配置加载逻辑默认通过类加载器读取classpath下的配置,不走文件系统路径查询逻辑,所以不受影响
解决方案
方案1:通过类加载器读取classpath资源(推荐)
放弃使用java.io.File相关的文件系统API读取,改用类加载器读取jar内部的资源流,示例代码如下:
// 基于Spring工具类的写法 import org.springframework.core.io.ClassPathResource; import java.io.InputStream; import java.util.Properties; public class KafkaConfigLoader { public Properties loadKafkaConfig() throws Exception { ClassPathResource resource = new ClassPathResource("kafka.properties"); Properties properties = new Properties(); try (InputStream inputStream = resource.getInputStream()) { properties.load(inputStream); } return properties; } }
如果不需要依赖Spring工具类,可以用原生JDK实现:
import java.io.InputStream; import java.util.Properties; public class KafkaConfigLoader { public Properties loadKafkaConfig() throws Exception { Properties properties = new Properties(); try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("kafka.properties")) { if (inputStream == null) { throw new RuntimeException("kafka.properties not found in classpath"); } properties.load(inputStream); } return properties; } }
方案2:打包时解压资源到jar包外(适用于必须用文件路径访问的场景)
如果你的业务逻辑必须拿到文件的本地路径才能使用,可以修改spring-boot-maven-plugin配置,打包时自动把指定资源解压到jar包同级目录:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>你的Spring Boot版本号</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> <configuration> <requiresUnpack> <!-- 替换为你项目的groupId和artifactId --> <dependency> <groupId>com.your.project</groupId> <artifactId>your-project-name</artifactId> <includes> <include>kafka.properties</include> </includes> </dependency> </requiresUnpack> </configuration> </plugin>
部署后可以通过new File("./kafka.properties").getAbsolutePath()获取到文件的实际路径。
注意事项
- 读取classpath资源时不要写死绝对路径,直接写资源相对于resources目录的相对路径即可,比如resources下的
config/kafka.properties直接写config/kafka.properties - 不要手动拼接
/resources/前缀,resources目录本身就是classpath的根路径,不需要额外加前缀
内容的提问来源于stack exchange,提问作者Boeggles
相关产品推荐
相关产品推荐

