Externalizing logging in Spring Boot apps - spring-boot

I'm trying to externalize logging configuration. However, any configuration I establish (e.g. -Dlogback.configurationFile=...) is wiped out the moment I call SpringApplication.run(). Is there a way to prevent this?

Try 'logging.config' (or use one of the the conventional locations, e.g. 'classpath:/logback.xml'). Docs here: http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-custom-log-configuration.

Related

Why spring.jpa.properties. prefix is not always required in Spring Boot properties

I learning Spring boot and found that in some examples use the same properties with the prefix spring.jpa.properties while other do it without prefix.
For instance:
The article explains second level cahche https://www.baeldung.com/hibernate-second-level-cache and autor shows example of needed properties ( example on autor's gitHub):
hibernate.cache.use_second_level_cache=true
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
But it did not work for me, and I spent few hours loking for the reason, but then i noticed, someone use prefix spring.jpa.properties. to get it working (Exact moment from video lesson):
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
Which perfectly worked for me.
So my questions are:
why are they working in different way?
how to understand which properties in which cases requires this prefix?
is it probably something related to my project settings OR Spring Boot version?
any other suggestions are appreciated :)
Thank you in advance!
There are a couple of things in play here. First the tutorial you use is using plain Spring not Spring Boot. Which means a manually configured EntityManagerFactory on which you directly can set the provider specific properties. Like hibernate.cache.use_second_level_cache.
As you decided to use Spring Boot you don't have a manually configured EntityManagerFactory (although you could!). Which means you are using an autoconfigured EntityManagerFactory. Properties for this reside in the spring.jpa namespace for properties.
As it isn't feasible to specify properties for each and every extension for Hibernate (or other JPA providers) only some commonly used ones are exposed like spring.jpa.generate-ddl and a few provider specific ones in the spring.jpa.hibernate namespace. However to set all the other properties in an autoconfigured way there needed to be something else. Hence the spring.jpa.properties prefix. Anything specified in there will be passed on as is (without the said prefix ofcourse) to the EntityManagerFactory for configuration.

Any way to split Spring Boot configuration into multiple properties files without having to specify an environment variable/system property

New to Spring Boot here, long-time Spring Framework user though.
I'm looking for a way to split my externalised configuration into multiple .properties files, for better readability and manageability.
I already saw this SO answer: having the ability to specify a list of configuration file names in spring.config.name (which, by the way, doesn't seem to be mentioned in Boot reference documentation, correct me if I'm wrong) would solve my problem perfectly, however that configuration property can be specified only via system properties or environment variables. If I try to specify it inside my application.properties file, it gets ignored. The same happens for spring.config.additional-location. I understand this happens because, when application.properties is read, it's too late to tell Spring Boot to search for different externalised configuration file names. However this is not a proper solution, because the way I split my configuration should be an "implementation detail" that the consumer of my application shouldn't be aware of, so I don't expect the consumer to specify an external parameter otherwise my application breaks out-of-the-box.
I think that a way to do this should be provided. Perhaps some import mechanism for .properties files or the ability to specify spring.config.name even in application.properties (some known and reasonable limitations would be acceptable).
The best I could find out is to use #PropertySource, but this is not profile aware: unless you use some ugly nested class hack, or you put spring.profiles.active variable in the resource name (which will break if multiple profiles have been activated), you won't get the benefit you have for application.properties profile-specific files.
I was not able to find an "official way" to do this, apart from some statements from Spring Boot devs that say that they're rather promoting the use of a single (possibly giant...) externalised configuration file. It seems like this position is not so popular, judging from the post reactions on GitHub, and IMHO it really seems to be a basic feature missing. I have been working with multiple properties files in Spring Framework (using XML configuration) for years and I never felt that having an only huge file would have been better.
If I understand it right, in Boot 1.x this was in some way possible using the location attribute of #ConfigurationProperties, which is however missing in Boot 2.x.
Any suggestion?
Have you tried with Spring Profile?
What you can do is create application-file1.properties/yml, application-file2.properties/yml and put it in config location and then add spring.profile.active=<your env profiles>,file1,file2.
It will load the files.
This profile entry can be in bootstrap.yml, or JVM args to application, in Manifest-<env>.yml in case of Pivotal Cloud Foundry. Not sure on AWS and other cloud provider.
Hope this will help.

Spring Boot best practices for hiding or encrypting passwords

I have been using the Spring Framework for about 4 years now, and now Spring Boot for the last couple of months. My Spring MVC applications are usually deployed on a Java EE container such as JBoss/WildFly or WebLogic. Doing so allows me to use JNDI for things like datasources or any other sensitive data that involve secrets/passwords. That makes my app "consume" that JNDI resource based on its name.
Now with Spring Boot and especially for self-contained microservices (embedded tomcat), that information is now stored within the application (application.properties and/or in Spring Java Config classes), so versioned in Git.
That makes that information a lot more exposed to other developers, which I'm not very comfortable with. I also don't like having those details show up in SonarQube and Jenkins (through workspaces).
Question is: Are there any best practices for this specific requirement?
* UPDATE *
I see some articles here and there about the use of Jasypt, but I wonder if it's still a valid library to use since the last stable release is dated from 2014.
Thank you
You could consider using a vault. Spring supports a few of them out of the box. You can find more information here http://projects.spring.io/spring-vault/.
If you have spring cloud in your stack, then it's very easy. Use encrypt the value and put it in the application properties. Follow the instruction mentioned here.
Other way is, set the values as environmental variables and using the environmental variables in the application properties. Instructions here

properties file reload on change in server, Spring

i am using Spring 4.2.5 and jboss 7 server.
Is it possible to change in application.properties files and make server to reload changed data in application.properties file automatically on refresh without restarting server?
Please suggest on this. Any idea or steps or api to use anything to move forward.
Regards
Ideal way would be use spring cloud config
#EnableConfigServer. You will have separate config server pointed all the properties pointed. And a client will be able to access the properties. This allows you to change the properties on the fly in server with out need for any restart.
http://jeroenbellen.ghost.io/manage-and-reload-spring-application-properties-on-the-fly/

Having spring bean properties refreshed automatically from properties file

I'm using Spring 2.5.6. I have a bean whose properties are being assign from a property file via a PropertyPlaceholderConfigurer. I'm wondering whether its possible to have the property of the bean updated when the property file is modified. There would be for example some periodic process which checks the last modified date of the property file, and if it has changed, reload the bean.
I'm wondering if there is already something that satisfies my requirements. If not, what would be the best approach to solving this problem?
Thanks for your help.
Might also look into useing Spring's PropertyOverrideConfigurer. Could re-read the properties and re-apply it in some polling/schedular bean.
It does depend on how the actual configured beans use these properties. They might, for example, indirectly cache them somewhere themself.
If you want dynamic properties at runtime, perhaps another way to do it is JMX.
One way to do this is to embed a groovy console in your application. Here's some instructions. They were very simple to do, btw - took me very little time even though I'm not that familiar with groovy.
Once you do that you can simply go into the console and change values inside the live application on the fly.
You might try to use a custom scope for the bean that recreates beans on changes of the properties file. See my more extensive answer here.
Spring Cloud Config has facilities to change configuration properties at runtime via the Spring Cloud Bus and using a Cloud Config Server. The configuration or .properties or .yml files are "externalized" from the Spring app and instead retrieved from a Spring Cloud Config Server that the app connects to on startup. That Cloud Config Server retrieves the appropriate configuration .properties or .yml files from a GIT repo (there are other storage solutions, but GIT is the most common). You can then change configuration at runtime by changing the contents of the GIT repo's configuration files--The Cloud Config Server broadcasts the changes to any Client Spring applications via the Spring Cloud Bus, and those applications' configuration is updated without needing a restart of the app. You can find a working simple example here: https://github.com/ldojo/spring-cloud-config-examples

Resources