Loading spring application-*.properties - spring

I was wondering if there is a way to dynamically reference keys in multiple application-*.properties files in a spring application. The challenge I have is the property file names can be different for each app. I have tried various combinations of spring.config.location, spring.config.name, used ClassPathResource but no luck
For e.g. in src/main/resources I might have for application A application.properties, application-system-X.properties, application-system-Y.properties
For e.g. in src/main/resources I might have for application B, application.properties, application-system-P.properties, application-system-Q.properties

I am not sure whether I understand you problem correctly. But in Spring Boot you can dynamically use different application-*.properties by using profiles.
These profile-specific application properties can live inside and outside of your packaged jar (application-{profile}.properties and YAML variants).
I can also recommend to read the documentation on externalising your configuration with Spring Boot.

Related

Spring Log4j2 xml file location

using Spring 2.0.5 with Log4j2
Have found works as expected if I place the file log4j2.xml in the resources folder.
However, have found the log4j2 option of monitorInterval="60" to be super useful as if some production issue can increase logging on some class without a restart. However if log4j2.xml is embedded in the jar of course it cannot be modified. so far the best I have been able to do is use 2 copies of log4j2.xml one in the resources and the other in the folder running the jar from.
I can then run:
java -Dlog4j.configurationFile=log4j2.xml -jar myapp.jar
it seems to work the same if started from the maven spring-boot plugin or from Eclipse.
Have tried a number of things such as setting the classpath, the absolute file name etc. but no luck
My question is how can I remove the log4j2.xml file from the resources folder and only specify it on the command line when starting spring?
I am not entirely clear on your question but I can provide the following information which I hope addresses it:
Log4j 2.12.0 added support for Spring Cloud Config and enhanced the support for Spring Boot. As of that version you can include a file named log4j2.system.properties and place any system properties you want defined there. They will be set before Log4j initializes. So you can specify the full URL to the configuration there if you want instead of the command line. You can also add the definition to a file named log4j2.component.properties.
The support for Spring Cloud Config allows you to place the configuration in your Spring Cloud Config server. See Spring CLoud Config support for more details.
Spring Boot initializes logging at least 3 times. The first is usually because the SpringApplication class declares a Logger so logging is initialized before anything else happens. The configuration for that will use "normal" log4j 2 initialization. After that Spring influences how logging initialization occurs primarily because Spring Boot sets the class path to include the jars inside BOOT-INF/lib directory inside your Spring Boot jar.
By using one of the configuration options I outlined above you can move the logging configuration outside of your application and you should not require a logging configuration in the resources directory. In fact, if you look at the sample Spring Cloud Config Application in Log4j you will see it does not include a configuration file in it.

What are the different approaches to configure application.properties file in spring boot

One way is to directly edit appliaction.properties file in any editor and write the contents.
Is there any other external approach to do the same because in one of my project, I am unable to find anything in application.properties file when I open it in editor but when I run the application I get some information out of application.properties file.
The properties may be configured in many different standard ways with SpringBoot. I think the best way to identify where your parameters are is to list the locations given in the SpringBoot configuration documentation and check if your parameters are here.
EDIT List the locations :
Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
#TestPropertySource annotations on your tests.
properties attribute on your tests. Available on #SpringBootTest and the test annotations for testing a particular slice of your application.
Command line arguments.
Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).
ServletConfig init parameters.
ServletContext init parameters.
JNDI attributes from java:comp/env.
Java System properties (System.getProperties()).
OS environment variables.
A RandomValuePropertySource that has properties only in random.*.
Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).
Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).
Application properties outside of your packaged jar (application.properties and YAML variants).
Application properties packaged inside your jar (application.properties and YAML variants).
#PropertySource annotations on your #Configuration classes.
Default properties (specified by setting SpringApplication.setDefaultProperties).

Spring Boot external configuration without ignoring the packaged configuration

I am developing a Spring Boot JAR application and what I want is for some configuration properties to be found in an external path. I want something like this:
the jar to be located at /home/myapps/my-spring-boot-app.jar
the configuration to be located at /apps/configuration/app/config.properties
I have set the spring-boot-maven-plugin with layout:ZIP and I have tried with different configurations like spring.config.location="/apps/configuration/app/" and loader.path="/apps/configuration/app/" and it didn't work.
In some cases, it ignored my external configuration, and in some cases, it ignored my packaged configuration. I don't want to use the Spring Boot defined hierarchy, to have the configuration in ./config/
Thanks for the help
Acording to documentation: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html spring.config.location can accept more than one file, so you can try something like this:
spring.config.location=classpath:/application.properties,/apps/configuration/app/config.properties
or just directories:
spring.config.location=classpath:/,/apps/configuration/app/

Spring Boot - ignore application.yml / bootstrap.yml inside .jar file

I have a spring cloud application using config server for fetching configuration. We are using Spring Boot 1.5.4 & Spring Cloud Dalston.SR2.
For deployment purposes we are providing external bootstrap.yml file and specifying its location with spring.cloud.bootstrap.location parameter.
We already had some struggle with the fact that, for couple of properties, service fell back to .jar's bootstrap.yml / application.yml
The only way I could find to solve that, was changing name of external configuration files with spring.config.name and spring.cloud.bootstrap.name. Then, the original names from .jar won't be matched and taken under consideration.
Is there are other way to tackle that?
You could solve that by upgrading to Spring Boot 2.x because they fixed the behavior of spring.config.location (see https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Guide#configuration-location) which also affects spring.cloud.bootstrap.location in the same way
See also that question Different behavior of spring.cloud.bootstrap.location since Spring Boot 2

Spring with maven-shade-plugin

I am trying to use to versions of spring in the same application: the first one is a webapp with spring 2.6 and the second it a jar client, with spring 4.0.2. The client communicates with another application and will be a dependency for the webapp. The problem is that the classloader will just load one time the common classes from spring and it will certainly fail.
I tried to use ElasticSearch aproach of using shaded dependencies(maven shade plugin) and relocate spring from the client to a different package (from org.springframework to my.springframework) and the uber jar seems to be constructed fine.
The issue is that Spring is based on spring.schemas and spring.handlers for validating xml config files and loads this files from classpath (META-INF folder and this paths are hardcoded in Spring code - e.q. PluggableSchemaResolver). I modified this files to point from org.srpingframework to my.springframework.
At runtime it seems that the classloader reads these files from the webapp, which has this files but with the real spring path and the exception is something like
org.realsearch.springframework.beans.FatalBeanException: Class [org.springframework.context.config.ContextNamespaceHandler] for namespace [http://www.springframework.org/schema/context] does not implement the [my.springframework.beans.factory.xml.NamespaceHandler] interface.
To me it seems that is impossible to achieve what I am trying (use tho spring versions in the same application with one of them relocated). Any ideas here? Am I wright?:d

Resources