How to update environment value in property file using pom.xml - java

I have configuration.properties in configs/Configuration.properties where I have url path = http://finacial/dev3/api
http:// financial/{env}/api
I want to load the environment value from the pom.xml to replace dev 3 according to the environment property set in pom.xml.

You could use the filter option of the maven resources plugin, it does exactly that.
Variables can be included in your resources. These variables, denoted by the ${...} delimiters, can come from the system properties, your project properties, from your filter resources and from the command line.
E.g. if you have a property url in your pom
<properties>
<url>abc</ulr>
</properties>
and your .properties file contains a value ${url} and you include the file in the resource section of the pom, then ${url} will be replaced in the output file in the build target location by abc upon issuing mvn resources:resources
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>

Related

Why doesn't loading a file using the classpath loader and the 'classpath:' prefix work?

I'm trying to load a file using the classpath loader from within a Spring Boot application.
I'm just running it using Intellij.
It won't load, even though the file is in the resources folder.
This was due to the maven project configuration in the pom.xml file.
The fix was to include the file I wanted to reference in the build output.
Example pom.xml change:
<build>
<resources>
<includes>
<include>**/filename.ext</include>
</includes>
</resources>
</build>
The file then appears at: ./target/classes/filename.ext.
This then means I could reference the file as expected in my application configuration .yaml file as follows:
filename: classpath:filename.ext
Note: this answer was changed from the original.

Correct way to specify main and test resource directories in pom.xml for Spring Boot project

I have 2 application.properties file in my small Spring Boot project. One is saved in /src/main/resources/application.properties and the other is in /src/test/resources/application.properties.
Some values in main doesn't necessarily have to be present in test.
Problem : When I do maven clean -> update project -> maven install in Spring Tool Suite IDE, I get multiple
Could not resolve placeholder 'JMS_URL' in value "${JMS_URL}"... and so on
But if I delete the application.properties file in test /src/test/resources/application.properties the error goes away and I get a successful maven install build.
I searched online and found that you need to specify the resources directory in pom.xml if you get that error.
Like so :
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
In my case, adding that <resource> block still did not resolve my problem because it's only specifying the directory of application.properties in src/main/resources but not for test
What is the correct way of handling this kind of situation where you have 2 application.properties file in main and test resource folder?
I'd appreciate any comment.
Thank you.
The correct way of handling this kind of situation is naming the test properties file differently, like application-test.properties. Then you either run your tests with the test profile active or explicitly specify
#TestPropertySource("classpath:application-test.properties")
on your #SpringBootTest.
Both ways you'll have all your properties from the main application.properties and application-test.properties active with properties from the latter having a higher priority.
Leaving the test properties file with the default name (application.properties) completely overrides the main properties file as you might have noticed. This way the test properties file has to have all the same required properties as the main one for the tests to work.

Modify the content of a file when executing the Maven command in Unix

I'm using the Unix terminal to build Java Projects. And I have created few Shell Script(.sh) files to execute the Jar files. So those sh files contain the version name of the jar file.
So I come across on a new requirement that when I upgrade my version Of the POM by executing a maven command and simultaneously I want to change the sh file's content according to that.
As an example
content of
A.sh
#!/bin/bash
"-jar X.3.16.0.jar"
When I execute the command like
mvn versions:set -DnewVersion= X.3.17.0-SNAPSHOT
I want to change the content of A.sh to be like
#!/bin/bash
"-jar X.3.17.0-SNAPSHOT.jar"
I used to do this change manually. But in the long run it won't be a good idea. So I thought to solve this by two approaches.
Method 1
Implement a mechanism to listen to above mentioned maven command and find the specified text in the sh file and replace it.
Method 2
Implement a new Shell Script with the maven command included and find and replace the text in A.sh file. This newly implemented sh file will have an argument to take the new version.
Question:
What will be the best approach to solve this problem? If none of the above will do it please help me out.
Thank you!
You could use the filter feature of the Maven resources plugin. Usually the resources plugin simply copies files from the resources directory (default src/main/resources) to the output directory (default target/classes) and includes the files into the jar (or whatever packaging you are using). Filtering enhances this process by resolving variables within the copied files while writing them to the target directory. Variables could be all standard Maven properties or any self-defined value that is set in the pom. The current version of the project is referenced with ${project.version}.
Filtering is enabled by declaring a resource directory to be filtered. The easiest case would be to filter all resources:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
Another option is to have a separate directory for resources that should be filtered:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/filtered_resources</directory>
<filtering>true</filtering>
</resource>
</resources>
If src/main/filtered_resources contains a file with the text
echo Version: ${project.version}
the result would be after the build
echo Version: 0.0.1-SNAPSHOT
If the filtered scripts should not be copied to the target directory but to a separate directory, the copy-resources goal of the resources plugin is useful.

My java application does not read my files (maven project)

I have an application in a Java simple project. However, I need to paste this project to a Maven project. So, I basically made a simple Maven project, and I copied and pasted all my classes into it. I need a war to run in a server, and I need to run a Main like a Java application, because this application configures the war application. However, when I run Main, I get some errors that I wasn't having before:
java.io.FileNotFoundException: resources\config.properties (The system cannot find the path specified)
when in the code is:
input = new FileInputStream("resources/config.properties");
This didn't work either:
faceDetector = new CascadeClassifierDetector("D:/retinoblastoma/workspace/Resources/CascadeClassifiers/FaceDetection/haarcascade_frontalface_alt.xml");
How can I fix this?
In a simple Mavne project, all the resources should be located in src/main/resources.You can get the properties file then by (for a non-static method) :
Properties prop = new Properties();
prop.load(getClass().getClassLoader().getResourceAsStream("config.properties"));
For a static method, use :
<Class name>.class.getClassLoader().getResourceAsStream("config.properties");
Refer this link for more information :
Reading properties file
If you're using a "simple maven project", the maven way is for there to be a src/main/resources folder. Did you configure your pom.xml to do something different than that?
If you've done the jar creation portion correctly, the right way to get a file that's on the classpath is:
getClass().getResourceAsStream("/path/to/resource.ext");
The leading forward slash is important!
If the file is NOT on your classpath (in other words, this will be the case if the above doesn't work), you probably need to configure maven to use a different resources directory.
You do that like this (change the arguments as appropriate):
<build>
...
<resources>
<resource>
<targetPath>META-INF/plexus</targetPath>
<filtering>false</filtering>
<directory>${basedir}/src/main/plexus</directory>
<includes>
<include>configuration.xml</include>
</includes>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
<testResources>
...
</testResources>
...
</build>
Then, your file will be on your classpath and the above code will work. Read the linked documentation above for more information.

Eclipse: project version as a parameter in multiple files

I am developing a project which uses versioning:
version name is typed in POM file
It is also used as a part of to-be-created .msi file name : file_[version].msi
It is used in a service name, after this project is installed from .msi
Those params are kept in locations as follows:
a).properties file as a Spring param: version=0340
b)in pom.xml <package-version>0340</package-version>
c)as a <filename><version>.wxs file, used by build.xml
d) also in the abovementioned .wxs file as a MsiProductVersion = "3.4.0" (notice the dots)
Is there a way to define a parameter in some other config file, that would populate those files with proper data, as to keep the version in one place only. Now it is easy to overlook one param, and build a 340.msi which will display 330 Service as its name. I find it difficult since not all files belong to one model (like Spring).
You can configure Maven to replace "variables" in resources. Add this to your POM:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
...
</build>
Now you can use ${project.version} and it will be replaced with the version from the POM in all files below src/main/resources and src/test/resources.
As for the other files, you can either use an embedded Ant task in your POM or write a small script (Ant, bash, whatever you like) that reads the POM and creates the other three files from templates.
Another option is to write a unit tests which reads all files and makes sure that they contains the correct values. That way, the version won't be updated automatically but a) the version doesn't change that often (which probably causes your problem) and b) the tests are much more powerful than what you can do in a script (they can, for example, read&update binary files).

Categories

Resources