Automatic restart of jar when property file is changed - spring-boot

I have a requirement where I am deploying a jar with its application.properties file outside of it. Is there any way that when I change an property in application.properties the jar automatically detects the changes and restarts/redeploys itself?

#RefreshScope annotation is provided in spring-boot.
By use of this annotation, you can reload a property value(use inside your code) from .properties.
here is the link for reference :http://projects.spring.io/spring-cloud/spring-cloud.html (Search #RefreshScope).
The idea is to reload whole bean(which is annotated with #RefreshScope),after hitting /refresh end point & you do not need to restart webapp again.

Read about http://cloud.spring.io/spring-cloud-config/
One of options is to restart/reload application after change in properties files.

Related

In which class in the source code of spring-boot or spring is the application.yml or application.properties file processed?

In which class in the source code of spring-boot or spring is the application.yml file or application.properties processed?
For spring boot (version 2.x) the application properties are loaded from the environment into the context via a PropertySourceLoader.
In for example the spring-boot-2.6.3.jar we can find the following file:
META-INF/spring.factories
# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader
Where PropertiesPropertySourceLoader loads .properties and .xml files, and YamlPropertySourceLoader loads .yml and .yaml.
These are loaded with the SpringFactoriesLoader, which we can see in action in org.springframework.boot.context.config.ConfigFileApplicationListener (deprecated) or org.springframework.boot.context.config.StandardConfigDataLocationResolver (via ConfigDataEnvironmentPostProcessor -> ConfigDataEnvironment -> ConfigDataLocationResolvers) :
this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class,
getClass().getClassLoader());
You can read in the ConfigFileApplicationListener JavaDoc that the properties are indeed loaded with this class:
EnvironmentPostProcessor that configures the context environment by loading properties from well known file locations. By default properties will be loaded from 'application.properties' and/or 'application.yml' files in the following locations:
file:./config/
file:./config/*/
file:./
classpath:config/
classpath:
...
If you're interested in context loading from the environment in spring(boot), I suggest you setup your project with maven, download the sources jars, and have a look around in the mentioned factories file. You will find more relevant code in the org.springframework.boot.env and org.springframework.boot.context (config and properties) packages.
You can find your application.yml or application.properties at the src/main/resources. You can have as many as possible configurations for your spring boot application for every case. Lets assume that you have 3 local-profiles like demo, production and server, so you made 3 configuration and assumingyou set for active profile the demo at the application.yml . I hope you get the idea. Its the first thing that actually is running before the springboot is up.
Please look the officials docs !

Externalizing configuration for Hibernate Search

I am running hibernate search with spring boot. I have written a working configuration for my application. How ever, i want to externalize my configuration and use ./config/hibernate.properties instead of src/main/resources/hibernate.properties. After copying my properties file to the desired location, i am getting and exception:
nested exception is java.io.FileNotFoundException: class path resource [hibernate.properties] cannot be opened because it does not exist
Anyone with any idea on how i should tell spring to read my configuration file?
Move your configuration to an src/main/resources/application.properties file and prepend spring.jpa.properties. everywhere, so hibernate.dialect will become spring.jpa.properties.hibernate.dialect, for example.
Then you can use Spring features to move your configuration wherever you want. To move it to ./config/application.properties I suppose you will have to add #PropertySource("./config/application.properties") to one of your #Configuration classes, or something similar.
I'm sure you can also keep the hibernate configuration in a separate file (separate from the rest of your application configuration).
See https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html for more details about externalizing configuration in Spring Boot.
For some reason, it seems hibernate-search will prevent application from starting as long as a hibernate.properties configuration file does not exist. After trying for a while without success, i found a work around for my problem.
First, i created an empty hibernate.properties file and place it under src/main/resources.
Secondly, i moved all hibernate-search configurations to application.properties as follows:
spring.jpa.properties.hibernate.search.default.indexmanager = elasticsearch
spring.jpa.properties.hibernate.search.default.elasticsearch.host = http://my-server.com
spring.jpa.properties.hibernate.search.default.elasticsearch.index_schema_management_strategy = CREATE
spring.jpa.properties.hibernate.search.default.elasticsearch.required_index_status = yellow
This way, the application will start and spring will get all configuration from the externalized configuration as documented here.

Create Externalized Configuration in spring-boot along with profiles

I have a spring-boot application with annotations instead of context.xml.
In my src/main/resources folder I have: application-dev.properties and application-test.properties.
which work perfectly for different profiles (while running with VM option like -Dspring.profiles.active=dev)
Now I need to externalize this properties with file in /opt/software/Tomcat8/conf/app.properties
Some props override each other, some don't.
in Tomcat config context.xml I say:
<Environment name="app.properties"
value="file:///opt/software/Tomcat8/conf/app.properties"
type="java.lang.String" override="false"/>
How to use it via JNDI in my application configuring app with no XML but annotations in Spring-bot application class?
I need it to have priority to inner jar properties according to
Link to Spring-boot.doc
One solution I found was to have the vm argument -Dloader.path with the external path when executing the application. Please keep in mind if you're using a fat jar you may need to create the package in Zip model, otherwise it will not work.

Spring Boot does not load application.properties and Velocity templates

I have two projects - one is based on the "get started" example, second is from the spring-boot-samples. I build both with Maven and run both from Eclipse. The "spring-boot-samples" project loads application.properties and displays Velocity templates named by the Controller. The "get started" does not.
Same file structure for application.properties (src/main/resources/application.properties) and templates (src/main/resources/templates/**), both with src/main/resources set to "Use as Source Folder" in Eclipse. Same workspace, same JRE.
I compared the .classpath and pom.xml, but found nothing suspicious. Obviously there's a difference, but where do I have to look?
PS: I can load application.properties via #PropertySources, but
that should not be neccessary (see comments there)
is not necessary in the "spring-boot-samples" project
does not help concerning the Velocity templates
Thanks!
To fetch values from application.properties in spring boot, we need to specify some annotation.
application.properties must be in the path src/main/resources
class must contain #RestController annotation
#Value("${name}")
private String name;
Ah, one important difference:
#RestController delivers the response directly, meaning: Instead of resolving the template's name the String is passed to the browser. The reason should be #ResponseBody:
Annotation that indicates a method return value should be bound to the web response body.
Using #Controller instead solves the Velocity problem.
EDIT:
To close this thread: I will continue using #PropertySources to get application.properties, but it does not work without it. Just having application.properties in your classpath is not sufficient.

Accessing properties file from another module context

I use maven. My web application contains two modules and each has it's own spring context. First is packed to jar, the second one to war. The second one uses first module's jar and calls it's methods.
I need to add property file, which will be used by first module (via spring context). The main issue is that I should be able to access/edit this property file after war deployment.
How can I provide such a property file, that will be used in first jar module and can be changed after war module deployment?
Thanks.
Sorry, don't see the problem, you need to describe that better. From what I understood this is the way to go:
place a.properties in src/main/resources in the JAR module
use a PropertyPlaceholderConfigurer to make the properties available in the Spring context
it'll be packed in root of the JAR
the JAR ends up in WEB-INF/lib of the WAR which again is "root of the classpath" so to speak
Update, 2013-06-09
(question was updated based on comments to initial answer above)
Essentially what you seem to be looking for (still not quite sure) is how to load properties from a properties file that is not packaged with your WAR/JAR.
In this case you can skip all of the above steps except 2.
Use a PropertyPlaceholderConfigurer and specify the location of the file as classpath*:a.properties (see below)
Place a.properties anywhere on the classpath outside the WAR file.
Warning! Of course you can now edit the properties independently from releasing the WAR file but since Spring initializes the beans on application start and since all beans are singletons by default changes to the properties file won't become effective until you restart the app.
XML example
<bean class="....PropertyPlaceholderConfigurer">
<property name="location" value="classpath*:a.properties" />

Resources