@PropertySource in Jar for external file on classpath
I am trying to use the Spring framework annotation @PropertySource
in the Jar to load a properties file from outside the jar, but it cannot find 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 use it somewhere in the classpath.
I am using the following annotation in the class Config
.
@PropertySource('classpath:stc.properties')
And placed it stc.properties
in the same directory as the generated Jar file. I tried to explicitly list the classpath in the command java
, but it still can't 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 also tried using ./
as classpath and tried to specify the classpath (with both options) in the Class-Path
manifest jar attribute , but it always gives the same results.
source to share
Assuming you have two files, one for local for production
@PropertySources({
@PropertySource("classpath:application.properties"),
@PropertySource(value = "${ws.properties}", ignoreResourceNotFound = true)
})
And in tomcat or your jar file, pass this parameter
-Dws.properties=file:/path-to.properties
I added this to setenv.sh
APPLICATION_OPTS = "- Dlog4j.configurationFile = file: $ PATH / log4j2.xml -Dlog4j.debug = true -Dapplication.properties = file: $ PATH / application.properties
This is only possible with Spring 4
source to share
My environment was:
OS: Windows | Container: Tomcat | Java: 7 | Spring: 4.2.4 | Springboot 1.3.1 | Maven
Step 1 a (war) :
Add external properties file file to JVM system properties.
How do I run this off tomat; I did this by creating setenv.bat in<TOMCAT_HOME>/bin/setenv.bat
set CATALINA_OPTS=%CATALINA_OPTS% -Dexternal.app.properties=file:<PATH_TO_EXTERNAL_FILE>\application-prod.properties
Step 1 b (jar) :
Alternative if you are using from a can:
-Dexternal.app.properties=file:<PATH_TO_EXTERNAL_FILE>\application-prod.properties
Note the use of the file : at the beginning of the line.
Step 2 . In my application launcher class, I used annotation @PropertySource
to load specific properties of the environment application.
@SpringBootApplication
@PropertySources({
@PropertySource(value = "${external.app.properties.file}", ignoreResourceNotFound = true),
@PropertySource(value = "classpath:application.properties")
})
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
Step 3 :
Using external effects in a project
external / file / path / application-prod.properties
spring.datasource.url.ext = <PRODUCT_DATASOURCE>
/src/main/resources/application.properties
spring.datasource.url = $ {spring.datasource.url.ext}
Hope this helps others having the same problem.
source to share
you can use spring.config.location = file: / somepath parameter when starting jar where you give the path to the config file (can be relative).
More information in the docs
source to share