Spring Boot应用连接BigQuery遇FileNotFoundException求助
问题分析与解决
核心问题
- 路径配置缺失前缀:凭证文件实际存放在
src/main/resources/my-todo/目录下,但application.properties中仅配置了classpath:vm-dev-393108-80d765f9af09.json,缺少my-todo/路径前缀,导致Spring无法定位资源。 - 资源加载方式错误:使用
FileInputStream直接读取classpath路径是错误的——classpath资源在打包后可能嵌入JAR包中,并非本地文件系统路径,需用Spring提供的资源加载机制读取。
修复步骤
1. 修正配置文件路径
更新application.properties中的凭证路径,补上my-todo/前缀:
myapp.google.credentials.path=classpath:my-todo/vm-dev-393108-80d765f9af09.json
2. 改用Spring资源加载方式修改配置类
替换原有的FileInputStream,使用Spring的ResourceLoader或ClassPathResource读取classpath资源,以下两种方式任选其一:
方式一:使用ClassPathResource
@Configuration public class BigQueryConfig { @Value("${myapp.google.credentials.path}") private String googleCredentialsPath; @Bean public GoogleCredentials googleCredentials() { try (InputStream serviceAccountStream = new ClassPathResource( googleCredentialsPath.replace("classpath:", "") ).getInputStream()) { return GoogleCredentials.fromStream(serviceAccountStream); } catch (IOException e) { throw new RuntimeException("Failed to load BigQuery credentials", e); } } @Bean public BigQuery bigQuery(GoogleCredentials credentials) { return BigQueryOptions.newBuilder().setCredentials(credentials).build().getService(); } }
方式二:注入ResourceLoader(更推荐)
@Configuration public class BigQueryConfig { @Value("${myapp.google.credentials.path}") private String googleCredentialsPath; private final ResourceLoader resourceLoader; public BigQueryConfig(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } @Bean public GoogleCredentials googleCredentials() { try (InputStream serviceAccountStream = resourceLoader.getResource(googleCredentialsPath).getInputStream()) { return GoogleCredentials.fromStream(serviceAccountStream); } catch (IOException e) { throw new RuntimeException("Failed to load BigQuery credentials", e); } } @Bean public BigQuery bigQuery(GoogleCredentials credentials) { return BigQueryOptions.newBuilder().setCredentials(credentials).build().getService(); } }
3. 验证Gitpod中资源编译情况
在Gitpod终端执行以下命令,确认资源是否被正确编译到classpath目录:
ls target/classes/my-todo/
若能看到vm-dev-393108-80d765f9af09.json,说明资源已正确打包;若未出现,检查Maven/Gradle配置,确保src/main/resources下的文件都被复制到target/classes目录。
额外简化方案
可直接通过@Value注入Resource对象,省去路径字符串处理:
@Configuration public class BigQueryConfig { @Value("classpath:my-todo/vm-dev-393108-80d765f9af09.json") private Resource credentialsResource; @Bean public GoogleCredentials googleCredentials() { try (InputStream serviceAccountStream = credentialsResource.getInputStream()) { return GoogleCredentials.fromStream(serviceAccountStream); } catch (IOException e) { throw new RuntimeException("Failed to load BigQuery credentials", e); } } @Bean public BigQuery bigQuery(GoogleCredentials credentials) { return BigQueryOptions.newBuilder().setCredentials(credentials).build().getService(); } }
内容的提问来源于stack exchange,提问作者Thomas Dev
相关产品推荐
相关产品推荐

