Unable to retrieve values from property files in Maven - maven

Iam using maven pom.xml ( just started learning )
I had some .properties files (for eg: log4j.properties), I should be able to retrieve values from them either in pom.xml or in web.xml file , I mean if I use something like ${somename.version} in pom.xml or web.xml, this value should be retrieved from .properties files.
My properties files are under as below:
src/main/resources/log4j.properties
src/main/env/dev/config.properties
iam trying as below, BUT unable to retrieve values from properties files.. iam doing something wrong.
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/env/dev</directory>
<filtering>true</filtering>
</resource>
</resources>
please suggest me.

Your configuration is wrong, for reading properties from file use:
<filters>
<filter>src/main/resources/log4j.properties</filter>
</filters>
Your actual configuration is about what files should be filtered.
For more information and example go to: Maven Resource Plugin - Filtering
You can also use Properties Maven Plugin

Resource filtering is meant to set a property in pom.xml and then use it in a property file.
with ${somename.version} in log4j.properties and the appropriate code in pom.xml your ${somename.version} is replaced with what you typed in pom.xml
for example inside pom.xml
<property>
<name>somename.version</name>
<value>123</value>
</property>
in your log4j.property
${somename.version} will be replaced by 123
you will find your file with the replaced value inside the target directory after you launch a mvn package
resources filtering is used when you package with profiles. each profile can change the properties in pom.xml
your properties can hold values that change with environnement like configuration for windows or configuration for linux

Related

Maven exclude resources not working as expected

I am trying to exclude from a build all YAML resource files, but the ones with a prod clause within the filename.
For example, given that my resource directory contains application-dev.yaml, application-test.yaml and application-prod.yaml, I would like application-dev.yaml and application-test.yaml to be excluded and application-prod.yaml to be kept.
The portion of my POM that deals with the resources is below:
<build>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<excludes>
<exclude>**/*-!(prod).yaml</exclude>
</excludes>
</resource>
<resource>
<directory>${project.basedir}/web/WEB-INF</directory>
</resource>
</resources>
However, exclusion does not work and all YAML files are copied, including application-dev.yaml and application-test.yaml.
I tested the exclusion pattern in Bash shell by ls *-!(prod).yaml and it worked as expected.
At this point I am lost and am looking for the community assistance.
I thank you all in advance for your thoughts and comments.
In order to solve that I would go with maven profiles and resource plugin maven resource plugin
You can have variables to the resource file name according to what you need (prod, dev, etc)

maven resources plugin - How to filter from external file?

I need to configure some log4j2.xml file based on some properties and those properties vary according to the environment. For example I set log.org.hibernate=info for development and log.org.hibernate=error for production etc.
I'm using maven resources plugin as shown below and it's working fine.
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<filters>
<filter>${project.basedir}/src/main/resources/env/prod.properties</filter>
</filters>
Now I need to filter external properties file and set those properties to the same log4j2.xml file. But AFAIK resources plugin doesn't allow external file filtering.
How can I read the properties from external properties file (outside of my project directory) and set them to an inner resource (such as log4j2.xml file)?

Maven resource filtering - Explicitly specify which files require property injection

Does the Maven resources plugin allow a flexible way to exclude certain files during the injection of Maven profile properties?
I don't want to exclude the files from assembly, just from the injection phase.
The project I'm working on defines unique Maven Profiles (and corresponding properties) in Settings.xml for each deployment environment. When the project is built the following steps occur
The projects POM defines the resources folder as the target to apply resource filtering
The resources folder contains .XML and .PROPERTIES files
During mvn:deploy Maven injects Profile properties into the .PROPERTIES file as expected
Maven also injects Profile properties into .XML files. This is not desired behavior (these files contain placeholders which allow the project to flexible inject values during deploy of the application)
The resource plugin provides configuration options to define include and exclude options however choosing the exclude option will also exclude the specified file from the assembly folder which is not desired.
Is it possibly to tell Maven which files should have placeholders replaced?
You are probably using the filters mechanism, for which you can decide whether to apply it to a certain folder and which filter should be applied to that folder.
Given the following sample POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>resources-example</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<filters>
<filter>src/main/filters/filter.properties</filter>
</filters>
<resources>
<!-- configuring an additional resources folder: conf -->
<resource>
<directory>${project.basedir}/src/main/conf</directory>
<filtering>true</filtering>
<excludes>
<exclude>*.txt</exclude>
</excludes>
<includes>
<include>*.properties</include>
</includes>
<targetPath>${project.basedir}/target</targetPath>
</resource>
</resources>
</build>
</project>
Note the filters section within the build section. Here we are telling Maven where how filter is, providing placeholders replacement.
Note then the <filtering>true</filtering> addition to a new resource configured afterwards and related includes/excludes patterns. As such, Maven will filter only the *.properties files of this folder.
Now, src/main/conf can contain a conf.properties file with the following content:
## add some properties here
property.example=#property.value1#
property.example2=${property.value2}
(Note the ant and maven style placeholders.)
While the src/main/filters (you need to create this folder) contains the filter.properties file with the following content:
property.value1=filtered-value1
property.value2=filtered-value2
Running the build you will get the conf.properties file in the target directory with the following content:
property.example=filtered-value1
property.example2=filtered-value2
Now, if your filter (file name) is a property injected by a profile, you can then inject different filters depending on the environment and only targeting certain files.

I can't get maven to use properties defined in ~/.m2/settings.xml?

I am using ~/.m2/settings.xml to store a number of property names used throughout the pom.xml files in my project. If I make the XML invalid (by adding another < for example), maven immediately generates an error, saying that it cannot parse that file. If I leave the XML valid, settings in my appBeans.xml file do not pick of references to properties defined in settings.xml.
Has anyone experienced this problem? I am sort of at my wits end here.
Reflecting properties from Maven configurations works by resources filtering.
Make sure your settings.xml, project pom and the target xml file contain correct configurations and reside in correct places.
If I understood correctly, you want to store a property name and value in the settings.xml so the props can be used in your project files. I'll provide a working example:
Define a default profile and properties in settings.xml:
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<someProp>Value</someProp>
</properties>
</profile>
</profiles>
Define resource folder's filtering=true in pom.xml:
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
Define the property in the xml file (that resides in the src/main/resources folder):
...
<element>${someProp}</element>
...
After this you should see the filtered result e.g. in target/classes/appBeans.xml.
Bear in mind that if you're using Eclipse & m2eclipse or similar plugin, it probably won't start using the updated settings.xml without restarting Eclipse and it's automatic build will sometimes overwrite your files in the target folder. I'm talking from experience here :)
Maven properties do not get reflected in miscellaneous XML files.
If you add one of these properties to the <properties/> element of the specific pom that runs the specific plugin that reads allBeans.xml, does that work? I believe that it will not, and your problem will turn out to be adding to the <configuration/> for the plugin to pass the maven properties to it.
If you edit your question to show the plugin that processes appBeans.xml I can make this more specific.

How to filter resources when using maven jetty plugin?

I have an XML file (urlrewrite.xml) that needs a property placeholder resolved. I enable Maven filtering to achieve this. This works fine for the assembled WAR file.
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
The problem is when trying to run the application in development mode using the maven-jetty-plugin (Maven Jetty Plugin), as maven jetty:run .
The file in question, urlrewrite.xml, is located in the src/main/resources directory, and therefore should (and does) ends up in /WEB-INF/classes (or target/classes for maven jetty:run).
The URLRewriteFilter config specifies the location of the config file as follows:
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
<init-param>
<param-name>confPath</param-name>
<param-value>/WEB-INF/classes/urlrewrite.xml</param-value>
</init-param>
</filter>
This will work at deployment time. However, Using the jetty maven plugin, URLRewrite will die with a NullPointerException because it uses context.getResourceAsString("/WEB-INF/classes/urlrewrite.xml") in order to load the config file. Jetty returns null for this because when running the application from workspace it resolves /WEB-INF/classes/... to src/main/webapp/WEB-INF/... . The file does not exist there because the WAR has not yet been assembled. It should instead pull the resource from target/classes/urlrewrite.xml.
If that is obscure to you, then you probably won't be able to answer this question because I suspect you will need to be a Jetty guru to figure out a workaround (hint: that's a challenge!).
Does anyone know a way around this? I have also tried the following workarounds to know avail:
Put urlrewrite.xml under a new directory, src/main/webResources and add it to the maven war plugin <webReources> and enable filtering. That will copy it's contents in the appropriate location when the WAR is packaged, but will not make it available for jetty:run
Some other hacks I can't even remember ... (will update if I do)
In summary, maven-jetty-plugin needs the file to be under src/main/resources/webapp/insert path and filename in order to be available for the maven jetty:run command ...
Thanks for you help ...
Sincerely,
Lloyd Force
Answered my own question.
Upgrade maven-jetty-plugin to at least 6.1.12
See this wiki page on 'Configuring Multiple WebApp Source Directory' (available since jetty-6.1.12.rc2 and jetty-7.0.0pre3)
Add some magic to pom.xml:
First, add a new directory (src/main/webResources) for your filtered web resources and add a <resource> element:
<resource>
<directory>src/main/webResources</directory>
<filtering>true</filtering>
<targetPath>../jettyFilteredResources</targetPath>
</resource>
That will copy the files to target/jettyFilteredResources (we will reference this later). This directory will NOT get copied to your packaged WAR file, it is for jetty only!
Add the following element to your maven-war-plugin <configuration> element:
<webResources>
<resource>
<directory>src/main/webResources</directory>
<filtering>true</filtering>
</resource>
</webResources>
That will ensure everything is packaged up for your real WAR file.
Finally, tell jetty to use the resources your copied especially for it, by added the following snippet to your <baseResource> element:
<baseResource implementation="org.mortbay.resource.ResourceCollection">
<resourcesAsCSV>src/main/webapp,target/jettyFilteredResources</resourcesAsCSV>
</baseResource>
Now everything will worketh! (Well, technically I haven't tested the production WAR yet, but ... blah ... it should work too).
If anyone has a better answer, I will accept it provided the answer is provided in a reasonable amount of time (say 1 day).
I think the answer in this other question is better:
Running resource filters when using jetty:run
Basically, instead of running 'mvn jetty:run' you have to use 'mvn jetty:run-exploded'.
The only drawback is that it needs to build the WAR file, which might be expensive in some cases. If that's not an issue for you, then I guess it's better.
add this to pom.xml:
<resources>
<resource>
<directory>src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>../jettyFilteredResources</targetPath>
</resource>
</resources>
and this is how embedded Jetty server should look like:
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.1.3.v20140225</version>
<configuration>
<webAppConfig>
<descriptor>target/jettyFilteredResources/web.xml</descriptor>
</webAppConfig>
<scanIntervalSeconds>3</scanIntervalSeconds>
</configuration>
</plugin>
woila! thanks #les2 for inspiration ;-)
I found another way.
build the project and add the target folder as extra classpath.
<webAppConfig>
....
<extraClasspath>${basedir}/target/mywebapp</extraClasspath>
....
</webAppConfig>

Resources