@PropertySource in a Jar for an external file on the classpath

brianmearns picture brianmearns · May 6, 2015 · Viewed 28.2k times · Source

I'm trying to use the Spring framework's @PropertySource annotation in a Jar to load a properties file from outside the jar, but it's not finding the file.

I need the properties file to be external to the Jar so it can be edited. I don't know the exact location where the file will be, I figured I could just have it anywhere on the classpath.

I'm using the following annotation on my Config class.

@PropertySource('classpath:stc.properties')

And placed stc.properties in the same directory as the created Jar file. I tried specifying the classpath explicitly in the java command, but it still cannot find the file:

java -cp . -jar stc.jar
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load bean class: com.example.stc.Config; nested exception is java.io.FileNotFoundException: class path resource [stc.properties] cannot be opened because it does not exist
        at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:162)
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:299)
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:243)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:254)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:94)
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:609)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
[...]

Etc.

I've also tried using ./ as the classpath, and tried specifying the classpath (with both variants) in the Class-Path attribute of the jar's manifest, but it always gives the same results.

Answer

vsingh picture vsingh · Mar 22, 2016

Assuming you have two files, one for local one for production

@PropertySources({
        @PropertySource("classpath:application.properties"),
        @PropertySource(value = "${ws.properties}", ignoreResourceNotFound = true)

})

And in tomcat or your jar file , pass on this parameter

-Dws.properties=file:/path-to.properties

I added this in setenv.sh

APPLICATION_OPTS="-Dlog4j.configurationFile=file:$PATH/log4j2.xml -Dlog4j.debug=true -Dapplication.properties=file:$PATH/application.properties

This is possible with Spring 4 only