Search code examples
javaspring-bootdependency-properties

@PropertySource returns 'Properties location not resolvable: (No such file or directory)'


I have a config file that is meant to use @PropertySource to set values. However it seems like it is not working (below)


@Configuration
@PropertySources({
        @PropertySource(value = "file:/Users/myUser/etc/secrets/credentials.json",
                ignoreResourceNotFound = true),
        @PropertySource(value = "file:/Users/myUser/etc/secrets/secret.id.properties",
                ignoreResourceNotFound = true)})
public class SpringConfig {
    @Value("${secret.id}")
    private String projectID;

    @Autowired
    private Environment env;

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    public String getId() {
        return env.getProperty("secret.id");
    }
}

I have set up dummy files in /Users/myUser/etc/secrets and have defined both credentials.json and secret.id.properties files. However when I run the application and call the config file's getId() method, it returns the id that is defined in the application.properties file, not in the @PropertySource path '/Users/myUser/etc/secrets/secret.id.properties' I suspect it can't find the path. (same for credentials.json) But the path file is definitely correct.

By the way, the inside of secret.id.properties file is:

spring.cloud.gcp.bigquery.project-id=project-id

How can I have the code actually fetch from the files in etc/secrets/ instead of from my applications.properties (or have my secrets/secret.id.properties be put into spring.cloud.gcp.bigquery.project-id=${spring.cloud.gcp.bigquery.project-id} in my application.properties?

I also tried to define in my applications.properties file

spring.cloud.gcp.bigquery.project-id=${secret.id}

and tried

spring.cloud.gcp.bigquery.project-id=${spring.cloud.gcp.bigquery.project-id}

but they both don't work and gives me an error.

I also checked file path


Solution

  • Welcome to stack over flow community.

    I have tried running your sample code here assuming you are providing absolute path in value field of @PropertySource. You have configured the annotations correctly, and everything spring is doing is as expected.

    To understand what is happening, we need to understand the order of external properties which gets considered by spring

    You are putting properties in 2 places:

    1. external file (credentials.json & secret.id.properties not named as application.properties or application-{profile}.properties) 2.application.properties inside your jar

    So as per order of preference of property, application.properties in your jar gets precedence over the external property not named as application.properties (credentials.json & secret.id.properties i.e. @PropertySource annotations on your @Configuration classes.).

    To verify this, you can comment out property in application.properties in your jar, and the properties from external files will be loaded.