What is the best place to store the application.properties file for a Spring boot application? - spring

I have an application.properties file which I have placed at the same level as the src folder. Things are working correctly. But, is this the standard place to keep this file? What is the best practice?

I place them at src/main/resources. Some would prefer src/main/resources/config. When deploying, I put the customized properties at the same folder where the jar is placed. Again, some would prefer the config sub folder.
Spring Boot picks the files from these locations by default.

Under src folder create another folder named config let's say. Here create another folder named local. Than place your file here. This structure is used when you want to deploy to different servers(i.e. local, test, live).
Then you can create profiles and for example you can configure Maven to choose the proper application.properties file located in one of these folders to create the war and deploy.
So have something live config/local/application.properties and at least config/live/application.properties
UPDATE
What IDE are you using? You need to declare the path as a resource path. See how to do that depending on what you are developing. At build time, the path need to contain some resources, i.e. one or more folders in which the .properties files will be placed.
You can also try the path sugested in another answers src/main/resources (it is more explicit I agree) but the thing is that you can place your resources anywhere but you need to declare the location as a resource location.

Related

spring boot config server properties files under different folders?

Does anybody knows if we can store the properties file under different folders on github and then spring-boot config server can read those files?
for example if my repository for properties file is:
https://github.com/chetankokil/configfiles
Can i have as many folder as i want under config-files repository and then these folders will have properties files under it? Can it be done?
I would suggest to take a look at Spring Could Config module. Spring ecosystem has your use case covered and it's better to follow proven footsteps rather than creating your custom solution.
You can create various directories in Github and provide bootstrap.properties file in your project. A sample bootstrap file is shown below
spring.cloud.config.uri=<your config server url>
spring.application.name=<your folder name in github>
spring.cloud.config.label=<github project branch name>
spring.output.ansi.enabled=ALWAYS
spring.profiles.active=<active profile in spring>

Creating flows in subfolders in apps folder in mule

I have created a flow under a subfolder in src/main/app in mule. So now I have a global folder under src/main/app and I have created a flow in the global folder.
When I do a maven build and run the project I am getting the errores config for app not found.
Is there ny work around for this problem,
Note : config.resources gets automatically updated with all .xml file with corresponding sub folders when I do a maven build.
I tried to put a flow in a subfolder under apps like you did but by doubt where confirmed.
When Mule is preparing the zip is not scanning and including the subfolders of /app in the main app folder on deploy but under classes, this causes the error that conf file cannot be found.
At this point if you really want to have flows in subfolder you have only one option:
Move your shared resources flow in src/main/resources/ for example under a folder flows
Add a spring include to your test.xml flow in this way
<spring:import resource="flows/shared-resources.xml"/>
This will include the other flow in your test flow and it will be virtually the same than having them listed in the mule-deploy.properties
Note that if your common flow contains logic that could potentially be reused on multiple mule apps you can also put it in a separate mule app that you can package as jar and include as a dependency.
Just google create mule commons libraries if you want to know more, I wrote a blog post about it but link it here will look like self promotion.
Hope this helps

Spring Relative Path File Resource In Application Context

I have a quick question about getting spring to read a file from the application context that is external to the project. I have two projects; 1) Project A 2) Project Database. Project A has the following structure;
ProjectA
|-src
|-main
|-webapp
|-WEB-INF
|-config
|-spring
Project Database has the following structure:
Project Database
|-db
|-scripts
|-deltas
In the spring directory of Project A I have a dao-context file. In this I have configured an embedded database, however I want to initialize the database with scripts from project database. Specifically in from directory deltas.
I know the embedded database config should like the following:
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="someSchema.sql"/>
</jdbc:embedded-database>
However I am trying to determine the best way to reference the scripts in Project Database. In other words would should be the value of location if I want to use scripts in locations. A few details:
Both projects would be checked out together on the same hierarchy.
Furthermore this database would only be used to run the tests, not the actual production code. So what ever the solution it should be compatible with my build script when I run tests tasks.
Lastly I want to avoid an absolute file path, because this will be run on multiple machines.
Any ideas?
Cheers
EDIT: Both projects are just folders and not jars. Neither projects are in each others classpath. Other than the fact that they are in the same directory there is no relation.
EDIT 2: Another scenario (and likely to happen) is that the db scripts could be in the same project as ProjectA , but not in the classpath. For example the directory structure could look like this:
ProjectA
|-db
|-scripts
|-deltas
|-src
|-main
|-webapp
|-WEB-INF
|-config
|-spring
If this was the case how would I access the scripts in the 'deltas' directory from the 'spring' directory?
I thing I have (more or less) understood what your asked, but there are many caveats.
First, when developping apps, there are 3 categories of paths :
source paths containing java sources (will be compiled), and other configurations or data files (will be copied)
target paths generated from the previous ones that are assembled in jars, or wars (or ...)
data paths that may contain data files, or file databases outside of a jar or war.
A web application is normally executed independantly of its source path, eventually on another machine : you build the war and deploy in on a servlet or JEE container.
What you can do is use an environment variable, a system property or a property value to set the root of a data path in the web application. Spring is kind enough to allow environment variable to override property values when using a PropertySourcesPlaceholderConfigurer to set ${...} values in an application context. Then you use that value to get access to your datas outside of the project.
In your example, you define such a property for the db location, and access all your database configuration relatively to that location.

Externalizing static content from a WAR and serve both on jetty

In my project I use Maven to package a web application to a WAR which is later deployed to Jetty using a custom Maven plugin on CentOS. The custom plugin is used by every project that deployes to a production environment. There is now a requirement that all static content (like web site text, properties) is packed outside of the WAR so that it can be changed in production without requiring a new release cycle. I am unsure how to achieve this externalization.
The Jetty server has the directory structure described in Jetty quick start guide. Currently, the web application already offers some .properties files which can be altered externally, and these reside in the resources/ directory. These files are moved here by the custom Maven plugin. The WAR resides in the webapp/ folder. One option for my problem is to use <packagingExcludes> of maven-war-plugin to not include e.g. *.xhtml and *.properties in the WAR. Later, I can use the custom Maven plugin to move excluded files to resources/ directory. But, I have a feeling this is not the correct way to externalize static content... Shouldn't xhtml files live in webapp/ folder while the only the properties file live in resources/ folder?
I have also researched the option of deploying the WAR as exploded, but I am unsure of the implications of such. Clearly, the changes in the exploded WAR files will be overwritten in the next deploy, but the idea is to do static changes both in development and production. Also, I am not sure how to achieve WAR "explosion", is it something that Jetty does for your WAR if configured in jetty.xml or do I have to extract the WAR before deploying?
Lastly, how do people serve static content in Jetty which can be altered in production? Do both the WAR and static files live side by side
The Jetty resources folder should not be used for application files. A J2EE web application (war) should be self-contained -- and in Jetty, reside only on the /webapps folder -- and its only binding to the container (Jetty servlet engine) is via the web.xml deployment descriptor.
Since property files may be read from the classpath and the Jetty resources folder is part of the system classpath, a property file there could be read by the web application class loader. Note that there are other ways to read property files as well and the Jetty resources folder should not be used for application properties. Also, the application may not be portable as other application servers have different forms of webapp classloader isolation.
If the below architecture approach does not work for you, then your only approach would be to expand (explode the war) in the /webapps folder and hope for the best when files are edited.
Tackling this from a different angle,
- if your web application depends on .properties and .xhtml files in order to function properly, then these files are probably not 'content'. The fact that there is a business process that requires them to to be updated ad hoc does not make them content.
- 'content' is something like text, images, and videos that is added, edited and removed by an administrative user. The application does not depend on it for correct execution, it merely reads and passes it on the browser.
Suggestions:
I would suggest that you deploy your application every time there is a change to the .xhtml or .properties files change. If the editors of these files are power business users, you might think of a git push-pull tool for them and a continuous build hook, so that when they make changes and push them to the git repository, the application gets tagged with a newer version and gets built and deployed. If there is a problem (tag not closed in xhtml), then it would be easy to roll back to the last tag.
Alternately, if the changes are minor (such as text descriptions), then modify the application to read them from an arbitrary external file (outside the webapp) -- a location that is provided to the webapp on startup. You can then package a 'default' version of the file in the webapp, but the code would attempt to look in the specified external location first.
I discovered that you can add HTML tags to properties and later use <h:outputFormat> to fetch these properties with parameters. Also, you can do pretty neat stuff with property files as described in MessageFormat API.
My solution was to keep the .xhtml files inside the WAR, but use simple HTML snippets properties from the default resource bundle which is based on a .properties file. These properties were included in the .xhtml using <h:outputFormat>and <h:outputText>. This allows the user to add simple styling like bold and underline to the snippets.
The properties file are copied to the Jetty resource folder using the custom Maven plugin, so I have kept the .properties files in the WAR. For some reason the Jetty resource folder has precedence over the packed .properties files, so this works out fine. Also, as Akber pointed out, I will have the default versions of the properties available if for some reason the WAR was moved to some other application server where the resource folder is not available.
Of course, with this approach the code can break if malformed HTML is placed inside the snippet properties, as pointed out by Akber, but it works for our application as it is very small. I may never have done this if this was a much larger application, but then I might have gone for a database based solution for adding static text (like Joomla/Drupal/Wordpress).

Spring in production

What is the best practice to make changes in beans.xml file in production environment?
Lets imagine Hello World application with one Interface and 2 Implementations. After creating jar and running JVM how can we change implementation in beans.xml without opening jar and reassembling it afterwards?
Is it any trick that permits having beans.xml outside the jar, but without knowing the full file-system path?
On top of suggestion made by OrangeDog, I would suggest considering leaving the beans.xml inside your deployed application AND using the PropertyOverrideConfigurer mechanism.
Configure an override configurer to point to some fixed path outside of the application, something like /opt/configuration/something/override.properties would be ideal. If you can't use an absolute path, you can always try to play with file:../../.. style of paths. Then you can list only the changed values within the override.properties file.
Don't have the XML in a JAR. Your application should be deployed in at least a WAR, which the app server will probably "explode". The folder WEB-INF/classes will be added to the classpath. You can make changes to the exploded XML here and the app server should detect this and reload the app.
Edit:
If you are using plain Java SE, you can use a system property to pass the location of the XML file. System.getProperty("property") in code and -Dproperty=value on the command line.

Resources