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

Spring Boot生产环境无法加载resources下的Google API令牌JSON文件

问题描述

Spring Boot项目中,src/main/resources目录下存放着Google API令牌JSON文件,本地debug模式运行完全正常,但执行java -jar myapp.jar启动打包后的应用时,出现如下错误:

Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [google.service.GoogleDocService]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: no JSON input found
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1334) ~[spring-beans-5.3.23.jar!/:5.3.23]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232) ~[spring-beans-5.3.23.jar!/:5.3.23]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.23.jar!/:5.3.23]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.23.jar!/:5.3.23]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.23.jar!/:5.3.23]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.23.jar!/:5.3.23]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.23.jar!/:5.3.23]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.23.jar!/:5.3.23]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-5.3.23.jar!/:5.3.23]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.23.jar!/:5.3.23]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.23.jar!/:5.3.23]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.5.jar!/:2.7.5]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.5.jar!/:2.7.5]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.5.jar!/:2.7.5]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.5.jar!/:2.7.5]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.5.jar!/:2.7.5]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.5.jar!/:2.7.5]
        at palexy.deployment.DeploymentApplication.main(DeploymentApplication.java:13) ~[classes!/:0.0.1-SNAPSHOT]
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) ~[deployment-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) ~[deployment-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) ~[deployment-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65) ~[deployment-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [google.service.GoogleDocService]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: no JSON input found
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:224) ~[spring-beans-5.3.23.jar!/:5.3.23]
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87) ~[spring-beans-5.3.23.jar!/:5.3.23]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1326) ~[spring-beans-5.3.23.jar!/:5.3.23]
        ... 23 common frames omitted

相关配置

  • application.properties:
app.credentials-oauth2-file-path=/credentials-oauth2.json 
  • 已修改pom.xml的build配置,添加resources节点包含JSON文件,但问题依旧:
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.json</include>
            </includes>
        </resource>
    </resources>
</build>
解决方案

1. 修正资源加载方式(核心问题)

打包成jar后,resources目录下的文件会被嵌入jar包中,无法通过磁盘文件路径(如new File())直接读取,必须改用Spring的类路径资源加载方式:

方式一:注入ResourceLoader加载

import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import java.io.InputStream;

@Service
public class GoogleDocService {
    private final ResourceLoader resourceLoader;

    // 构造注入ResourceLoader
    public GoogleDocService(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    private void loadCredentials() throws Exception {
        // 加载类路径下的JSON文件
        Resource resource = resourceLoader.getResource("classpath:credentials-oauth2.json");
        try (InputStream inputStream = resource.getInputStream()) {
            // 初始化Google凭证逻辑
            // GoogleCredentials credentials = GoogleCredentials.fromStream(inputStream);
        }
    }
}

方式二:直接注入Resource

修改application.properties路径为classpath:credentials-oauth2.json(或去掉开头的/),然后直接注入Resource:

import org.springframework.core.io.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.InputStream;

@Service
public class GoogleDocService {
    private final Resource credentialsResource;

    public GoogleDocService(@Value("${app.credentials-oauth2-file-path}") Resource credentialsResource) {
        this.credentialsResource = credentialsResource;
    }

    private void loadCredentials() throws Exception {
        try (InputStream inputStream = credentialsResource.getInputStream()) {
            // 初始化Google凭证逻辑
        }
    }
}

2. 确认JSON文件已被打包进jar

执行命令jar tf myapp.jar,查看输出中是否包含credentials-oauth2.json。如果没有:

  • 检查JSON文件是否确实在src/main/resources根目录下
  • 确认pom.xml的resources配置没有被其他exclude规则覆盖

3. 避免在Bean构造器中加载资源

错误栈显示异常发生在Bean构造阶段,建议改用@PostConstruct注解延迟初始化逻辑,更符合Spring生命周期:

import javax.annotation.PostConstruct;
import org.springframework.core.io.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.InputStream;

@Service
public class GoogleDocService {
    private final Resource credentialsResource;
    private Object credentials; // 替换为实际的Google凭证类型

    public GoogleDocService(@Value("${app.credentials-oauth2-file-path}") Resource credentialsResource) {
        this.credentialsResource = credentialsResource;
    }

    @PostConstruct
    public void initCredentials() throws Exception {
        try (InputStream inputStream = credentialsResource.getInputStream()) {
            credentials = GoogleCredentials.fromStream(inputStream);
        }
    }
}

内容的提问来源于stack exchange,提问作者MinhSu - Justin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 22:27:33