Spring Boot properties file between develop phase and 'production' phase - spring

I have developed a simple Spring Boot application (not a web but a standalone one).
Inside my app I use a custom 'user.properties' file which properties like:
smtp.host=<development.somesmtp.host>
The ejecutable jar file that contains the packaged application includes that 'user.properties' file.
BUT, if the user of my application whants to change that property, he cant's because the properties file is inside the jar.
smtp.host=<production.somesmtp.host>
What is the correct way to approach this issue?

For me the solution was:
Use this annotations:
#Component
#PropertySource({"file:C:/PRONOM/user.properties", "classpath:user.properties"})
public class UserProperties {
Launch the app with the next command:
java -jar C:/PRONOM/pronom-0.0.1.jar --spring.config.location=file:C:/PRONOM/user.properties

Related

How can I tell Spring Boot to place some of the classes at the root of the jar instead of BOOT-INF?

I'm trying to set a custom log Handler in my Spring Boot (version 2.6.3) application. The result is a ClassNotFound as described in this other question
Can't override java.util.logging.LogManager in a Spring Boot web application: Getting java.lang.ClassNotFoundException on already loaded class
Based on the answer to that question, it seems I need my Handler and all its dependencies to be placed into the root of the executable jar.
Is there a direct way to accomplish this during the Maven build, i.e. not by extracting and repackaging the jar myself post-build?
This issue is a result of BOOT-INF fat jar structure introduced by Spring Boot 1.4.
There is currently no straightforward solution, and it appears some of the Spring Boot maintainers do not agree there is a problem, so it could be a long time before the situation changes:
Issue #6626: Make it easier to package certain content in the root of a fat jar
Issue #12659: Starting executable war with -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager produces a ClassNotFoundException
WORKAROUND #1
I had to do two things to get my application working again with a custom log handler. 1) use Maven Shade to package up the log handler with all its dependencies, and 2) launch the app with using the PropertiesLauncher class in the command line instead of using java -jar:
java -cp executable.jar:logger-shaded.jar -Dloader.main=mypackage.myapp org.springframework.boot.loader.PropertiesLauncher
The executable.jar, logger-shaded.jar, and mypackage.myapp are placeholders specific to my project, so adjust accordingly.
WORKAROUND #2
If the handler is loaded from code in a config class or from main() instead of being specified in the file loaded via java.util.logging.config.file, as discussed in the comments to the answer in this other question, then everything works as expected. I actually prefer this over Workaround #1 as it results in a smaller deployment, but it does require writing a few more lines of code.

Use External properties file

Am looking to pass variables at run time once war file is deployed on tomcat ..
How can i use application.properties whcih is in classplath along with another properties file ex. abcd.properties located at particular directory..Am basically looking to set additional classpath and read value from properties file in that path along with default classpath location for war deployment.
Am using Spring boot .One of the way is to pass all properties to database end , but am looking for a file based i.e properties based workout.
(Having multiple applications on same tomcat instance.)
Spring Boot App --> run as --> run configurations. Now here in VM arguments add Dproperties.location="Path of the properties".
Now, in your Spring Boot application use the annotation #PropertySource("file:${properties.location}/propertiesfileName.properties") just above the class declaration.
Autowire Environment in your class. use env.getProperty("propertyname").
You can access the values from application.properties as usual using #Value annotation. Hope this helps.

Running a Spring Boot application with multiple main classes

I am using Spring Boot with a multi module maven project, the structure looks like this
project
- project-rest-controller
- project-file-adapter
- project-library
Where project-rest-controller module contains the #RestController and has a main Spring Boot class to start the embedded tomcat, the controller will receive a POST and create a request and pass it to the project-library module.
Also, project-file-adapter module contains a Spring-Integration file adapter to pull for a file in a directory, read the file and create a request and pass it to the project-library module.
When I run the application using mvn spring-boot:run from within the parent directory, I get an exception with main class should be specified.
It seems that Spring boot allows to specify the main class in the following way
mvn spring-boot:run -Dstart-class=com.blah.App
but I have two main classes.
Should I start two apps?
one from project-rest-controller
one from project-file-adapter
This will start two JVMs and that's now what I am trying to do?

Externalizing property file and Application Context file - Spring XD custom module

Is there a way we can externalize the application-context and property files while deploying spring-xd custom module ? When i deploy the module, i just see the jar inside in xd/custom-modules/processor. However, The out of the box spring-xd modules has a folder structure like http-client/Config/httpconfig.xml and http-client/Config/httpclient.properties.
At least for properties it is possible to place them in xd/config/modules/type-of-module/module-name/module-name.properties. I didn't try out application context files yet.
For more details see here: XD docs: module configuration

Spring Property place holder / multiple applications within the same tomcat/jvm

Is there a way to use Spring 3 property place holder to load application specific properties without conflicting with other applications within the same tomcat/jvm ?
All of your application specific properties are residing inside your jar and tomcat will only make them available to your application.
Just put them under webapps/${app_war}/WEB-INF/classes/app.properties and your spring config will pick them up from classpath.
System properties via -D startup parameters are shared, but not application specific.

Resources