Property-placeholder default value separator - spring

Small question.
We use Spring 3.1 and seem to be having an issue with the value separator (The default value that is).
<context:property-placeholder ignore-resource-not-found="false" ignore-unresolvable="false" location="${app-conf-base-path:classpath:}environment/app-conf-${spring.profiles.active:test}.properties" />
We filter the properties being deployed based on maven environment profiles. If no maven environment profile was provided all environment property files will loaded in the war and put on the classpath.
The actual environment specific settings are loaded at runtime using spring profiles. The part that is giving us an issue though is ${app-conf-base-path:classpath:} because it seems he can not resolve this. I believe this is because the placeholder is split using the last occurrence of the default value separator.
Why we want this is because we want him to look on the app-conf-base-path unless this is not defined as JVM parameter. In that case he should look in the classpath.
I tried:
Placeholder configurer with a value separator == '?' with no avail.
Anyone got an idea of an alternative?

I solved the problem by making sure external configuration files are added to the classpath of the server when loading it's classloaders. This way I don't need a placeholder to point to a file:// type location.
I added a export line to the setclasspath.sh of tomcat to add the external file to the environment variable CLASSPATH.

Related

Quarkus #ConfigMapping: when no prefix defined, skip/ignore system and environment variables, only scan properties with defined keys

Some properties defined in my app are used by other applications in the same organization, so I cannot add a dedicated namespace before them to differentiate. While moving to Quarkus #ConfigMapping, I found Quarkus by default scans all system and environment variables as well as application scoped properties, and non-mapped properties will stop app from launching, showing a lot of "cannot find any root to map" error.
Quarkus YAML config is based on Smallrye config, which has:
smallrye.config.mapping.validate-unknown=false
to stop this behaviour.
https://smallrye.io/smallrye-config/2.11.1/config/mappings/#retrieval
For a Config Mapping to be valid, it needs to match every configuration property name contained in the Config under the specified prefix set in #ConfigMapping. This prevents unknown configuration properties in the Config. This behaviour can be disabled with the configuration smallrye.config.mapping.validate-unknown=false.

Spring boot external config override isnt working

I have an application.yml and application-qa.yml in my resources folder.
I have an external application-qa.yml.
I want the properties in the external application-qa.yml to override the matching ones from the default application.yml and from the internal application-qa.yml, I dont want to override the entire file.
Im adding this VM option (In Intellij): -Dspring.config.additional-location=file:{absolute/path/to/external/ending/with/application-qa.yml}
I also have in env variables (also in Intellij): spring.profiles.active=qa
And for some reason the override doesnt work, I get the value from the internal application-qa.yml instead of the external one.
Tried naming the external file as application.yml, didnt work.
UPDATE:
It does work if I remove application-qa.yml from the end of the path and just give a path to the folder where the file is, but I want to specify a file, I dont want him to take everything thats in the dir.
This is a change in behavior from 1.x to 2.x. The spring.config.location overrides the default instead of adding to it. We need to use spring.config.additional-location to keep the defaults. So if you want to override try spring.config.location instead.

Conventions for naming application.properties

In my Spring application, I am trying to use property-placeholder with profiles test,dev,prod. Also I would like to be able to load the default properties common which are common for all profiles.
<context:property-placeholder
ignore-resource-not-found="false"
location="classpath:application-common.properties,classpath:application-test.properties"/>
This however doesn't work correctly. I am not yet using the variable ${spring.profiles.active}, because it doesn't work correctly even without it. What happens is that whatever is after the hyphen application- is loaded in alphabetical order. Loaded is only the first one, the other one is ignored. So in this case, only -common is loaded. Strange thing is, if I remove the hyphen, it load both files.
Is there some hidden behaviour I am not aware of?
You can use #PropertySource to load 'common' property file.
#PropertySource({
"classpath:application-common.properties"
})
Load environment specific property file by using spring.profiles.active while running your application.
For example , spring.profiles.active=dev

Spring Boot configuration behaviour with #ConfigurationProperties and Command Line arguments

I seem to be having some funny behaviour with Spring boot on yaml property files im trying to load.
I have a Settings bean that is setup as follows :
#ConfigurationProperties(location = 'config.yml', prefix='settings')
public class Settings {
private String path;
...
}
I've explicitly told spring to look in the config.yml file for property values to bind to the Settings bean. This looks like this:
settings:
path: /yaml_path
This works well, however, I don't seem to be able to override these values from the command line i.e.
java -jar my.jar --settings.path=test
The value that is bound to the settings bean is still /yaml_path but would've expected that the --settings.path=test would override the settings in the yaml.
Interestingly, I've noticed that if i take comment out the path setting from the yaml file, the commandline argument value of test comes through.
Additionally, I've also noticed that if i change my config file from config.yml to application.yml and remove the 'location' attribute from the configuration properties file this gives me the desired desired behaviour, but means that I can't have multiple application.yml files in the classpath as it breaks my multi module application which has configuration files throughout.
Ideal world I would like be able to have modules read configuration from yaml files that contain safe values for that module (i.e. module.yml) and be able to override these values from the commandline if needed. Has anyone figured out how to get commandline arguments passed into the beans this way?
I have created a project on git hub to show case the issue
https://github.com/vcetinick/spring-boot-yaml-test
Running the application displays logging information about what settings are applied. i.e.
java -jar spring-boot-yaml-test-0.0.1-SNAPSHOT.jar --config.path=/test
should override the settings, however, the default /var/tmp is displayed
additionally, when using the application.yml configuration
java -jar spring-boot-yaml-test-0.0.1-SNAPSHOT.jar --app.path=/test
seems to behave as expected where the command line argument overrides the value but only works because its value is defined in the application.yml file.
Looks like the locations attribute is working as designed, however, seems to be at odds with the standard configuration paradigm setup by spring boot (https://github.com/spring-projects/spring-boot/issues/5111). It is meant to override the settings. It looks like this this feature may be removed in a future release of spring boot anyway (https://github.com/spring-projects/spring-boot/issues/5129)

How do I access Spring properties in a logback configuration

Is there a way to access Spring properties within a logback.xml file?
I know one can import a properties file if you know its location, but I'm using Spring profiles to control where the properties file should be loaded or not.
Is there done kind of connector that asked me to feed Spring data into logback? This would only be at startup; I don't need to be able to do this on the fly.
I'm guessing you do have to import a property file (common property file, non-environment specific one) that will contain the name of the property that you are going to use in the logback.xml, and that you want to optionally override the value of the property for some environment (you need at least one property file containing the name of the property, because you will be using that property in the logback.xml, and you need it to be available to be able to use it).
For the optional environment-override, how about including an additional property file? For example, we use both application.properties and application-${spring.profiles.active}.properties files. Then if we don't need to override the property for some environment, we simply don't include it in the environment specific property file (application-dev.properties, etc.)

Resources