Reading properties file values into pom.xml - maven

I've tried and follow this solution
How to read an external properties file in Maven
but with no luck.
I would like to read an absolute path(/home/tomcat/lib) from a properties file(which is in the same location as pom.xml) and set the value in the pom.xml
project.properties file contains:
myTomCat.lib.location=/home/tomcat/lib
pom.xml configuration contains:
<properties>
<envTomcatLib>${myTomCat.lib.location}</envTomcatLib>
</properties>
<dependencies>
<dependency>
<artifactId>MyJar</artifactId>
<groupId>MyJar</groupId>
<scope>system</scope>
<version>1.0</version>
<systemPath>/${envTomcatLib}/MyJar.jar</systemPath>
</dependency>
</dependencies>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-1</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>${basedir}/project.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
The problem is either at eclipse compile time or running "mvn install" that the placeholder ${envTomcatLib}/MyJar.jar, can't get resolved to /home/tomcat/lib/MyJar.jar and remains ${envTomcatLib}/MyJar.jar.
Can someone please assist?
Thanks

Values in the <properties> section are assigned when the POM is initially loaded. The properties-maven-plugin only affects plugin executions that come after the point where the properties were loaded. More detail in a similar answer I provided.
BTW, the Maven Reference Book has this to say about system scope: "Note that this scope is not recommended (you should always try to reference dependencies in a public or custom Maven repository)."

You may need to remove "/" before /${envTomcatLib}/MyJar.jar or give property value as home/tomcat/lib instead of /home/tomcat/lib. It may be the reason for not able to resolve your location.

Related

How can I override maven property values set by properties-maven-plugin's read-project-properties goal?

In one of our projects, we use the properties-maven-plugin's read-project-properties goal to read property values from a file which are then used for filtering resources. See this post for a discussion on the general purpose of this procedure.
We would like to override some of the values found in the file using a suitable profile defined in the developer specific settings.xml (the same way we override properties set in the POM).
This, however, does not work for the properties set by the properties-maven-plugin.
How can we achieve our goal?
As a work around, we are currently registering an additional, developer specific file with the properties-maven-plugin to achieve this effect but it would be much more convenient to use the regular way (profiles).
In more general terms, the question is: How do properties set by properties-maven-plugin's read-project-properties goal tie into the property definition precedence hierarchy of maven, which is described in this very helpful blog post.
I extracted the relevant elements of our POM into a toy project that demonstrates my issue. Here is the POM of the toy project:
<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>xxx</groupId>
<artifactId>MavenTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Maven Test</name>
<description>A maven project to test filtering and the maven-properties-plugin</description>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<executions>
<!-- Read properties from a file -->
<execution>
<id>load-filter-properties</id>
<goals>
<goal>read-project-properties</goal>
</goals>
<phase>initialize</phase>
<configuration>
<files>
<file>filters/filterTest.properties</file>
</files>
<quiet>false</quiet>
</configuration>
</execution>
<!-- The following execution is for debug purposes only -->
<execution>
<id>write-project-properties</id>
<inherited>false</inherited>
<goals>
<goal>write-project-properties</goal>
</goals>
<phase>package</phase>
<configuration>
<outputFile>filters/project.properties</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12-beta-1</version>
</dependency>
</dependencies>
</project>
I think you will find the answer here:
Modifications of project properties that happen during project lifecycle have no effect on the effective pom – it is just too late. Examples of such modifications include groovy scripts (via gmaven-plugin) and properties loaded from external files via maven-properties-plugin. So, why do we need them at all? Since they can be used by other plugins in runtime, when they are read directly from properties collection during plugin invocation.
Since the properties are read after the usual resolution they just override whatever was set in profiles.

Maven: set property in pom.xml from properties file

I have multi-module project with a lot of dependencies on different modules versions. At the moment versions are hardcoded and one needs to change them manually. So I decided to put all of them to a properties file and get properties values from it during project build.
Here is how I try to do it:
root pom.xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>./version.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
file version.properties
module1.version=1.1
module2.version=1.8
module3.version=5.4
example of module pom.xml
<properties>
<module1.project.version>${module1.version}</module1.project.version>
</properties>
<parent>
<groupId>com.mymodule</groupId>
<artifactId>test</artifactId>
<version>${module1.version}</version>
<relativePath>../pom.xml</relativePath>
</parent>
Build fails with:
Failed to execute goal
org.codehaus.mojo:build-helper-maven-plugin:1.7:parse-version
(parse-versions) on project ccm-agent: Execution parse-versions of
goal org.codehaus.mojo:build-helper-maven-plugin:1.7:parse-version
failed. NullPointerException -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to
execute goal
org.codehaus.mojo:build-helper-maven-plugin:1.7:parse-version
(parse-versions) on project ccm-agent: Execution parse-versions of
goal org.codehaus.mojo:build-helper-maven-plugin:1.7:parse-version
failed.
How can I read some properties from a file and configure pom.xml in correct way?
It appeared to be very simple at the end. I used initialize phase. Changing it to validate fixed the problem:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<phase>validate</phase>
You must not use properties / variable replacement inside of <parent> elements.
The main reason here is that Maven must read the parent POM before it can start expanding properties since the parent POM might define properties as well.

Can I have maven artifact run maven plugin when it is installed?

I have created a Maven plugin (called unpackTemplates) that unpacks a dependency jar file and copies resource files (in this case, templates) from it into a specific location in a project.
Right now, I put the following into the pom file of every project that has a dependency with templates. It looks like:
<project>
<groupId>DuriansAreDope</groupId>
<artifactId>DuriansAreDope</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugin>
<groupId>mycorp</groupId>
<artifactId>unpackTemplates</artifactId>
<version>1.0</version>
<executions>
<execution>
<configuration>
<groupId>com.mycorp.lib</groupId>
<version>1.0</version>
<artifactId>Lib-With-Templates</artifactId>
</configuration>
<goals>
<goal>unpackTemplates</goal>
</goals>
<phase>generate-sources</phase>
</execution>
</executions>
</plugin>
<pluginManagement>....</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>com.mycorp.lib</groupId>
<artifactId>Lib-With-Templates</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
The above project pom works for us. It calls the plugin and the plugin does it's job. However, we'd like to avoid adding the plugin section to the pom of every project.
It would make more sense to put that plugin section in the dependencies pom. This way the project pom does not need to be modified beyond adding the <dependency> tags as usual. And the dependency has it's plugin run wherever it is installed.
I've seen that the pom file for Gson contains a <build><plugins>...</plugins></build> section in it. When I give my dependencies the following pom files, however, the plugin is not run (although the dependency is found, downloaded, installed, etc correctly).
<project>
<groupId>com.mycorp.lib</groupId>
<artifactId>Lib-With-Templates</artifactId>
<version>1.0</version>
<build>
<plugin>
<groupId>mycorp</groupId>
<artifactId>unpackTemplates</artifactId>
<version>1.0</version>
<executions>
<execution>
<configuration>
<groupId>com.mycorp.lib</groupId>
<version>1.0</version>
<artifactId>Lib-With-Templates</artifactId>
</configuration>
<goals>
<goal>unpackTemplates</goal>
</goals>
<phase>generate-sources</phase>
</execution>
</executions>
</plugin>
<pluginManagement>....</pluginManagement>
</build>
</project>
Any ideas what I'm doing wrong, or if the Gson pom is simply doing something else entirely?
(NB: The groupId/version/artifactIds in <configuration> are necessary because they are (string) parameters to the plugin; presumably if I got the run-straight-from-dependency approach working I could refactor them away, but again, it's not even running the kludgy version with parameters.)
two points:
First I agree with khmarbaise in that you don't need a plugin of your own for those tasks. To unpack to a specific location you can use dependency:unpack-dependencies and outputDirectory parameter.
If you need more configuration you can use the assembly plugin to structure your artifact (which you want to unpack).
For the second point it seems to me that you want to use the contents of your lib-with-templates in many projects. Why don't you add the plugin and dependency to a parent pom which you include in every pom where you need it? Then you don't need to declare it in "every pom". If you don't really need it in every pom you can put it in a profile and choose a proper activation for it.
HTH!

Maven archetype creation : prototype pom

I am creating a maven archetype. In this I have a prototype project, which gets created for a user when the user calls the following command:
mvn archetype:generate -DarchetypeGroupId=xxx -DarchetypeArtifactId=archtype-yyyy -DarchetypeVersion=1.1.0-S5-SNAPSHOT -DgroupId=zzz -DartifactId=proj11
In the prototype pom, I want to use the 'archetypeVersion' property that I am specifying in the above command. Like this:
<dependencies>
<dependency>
<groupId>mmmm</groupId>
<artifactId>nte</artifactId>
<version>${archetypeVersion}</version>
</dependency>
This is not working for me. When the project is created, it still shows the dependency snippet in the generated pom exactly as it is posted above. It does not replace it.
Is this possible? Does maven allow this?
If yes, how can I do it?
I think simple way to do this is to use maven-replacer-plugin. You have to add next section to archetype /pom.xml:
<build>
...
<plugins>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.2</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals><goal>replace</goal></goals>
</execution>
</executions>
<configuration>
<file>target/classes/archetype-resources/pom.xml</file>
<replacements>
<replacement>
<token>\$\{archetypeVersion\}</token>
<value>${version}</value>
</replacement>
</replacements>
</configuration>
</plugin>
</plugins>
...
<build>
ie this code replace ‘${archetypeVersion}’ substring to current version of archetype. Your ‘/src/main/resources/archetype-resources/pom.xml’ contains next dependency:
<dependency>
<groupId>xxxx</groupId>
<artifactId>yyyy</artifactId>
<version>${archetypeVersion}</version>
</dependency>
After executing ‘mvn install’ command, the resulting file ‘/target/classes/archetype-resources/pom.xml’ will be contain archetype version number. Now you have installed archetype and can use its: ‘mvn archetype:generate ...’.
Easiest way I've found is to just add it as a defaulted variable in your META-INF/maven/archetype-metadata.xml as follows:
<archetype-descriptor
xmlns="https://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.1.0 http://maven.apache.org/xsd/archetype-descriptor-1.1.0.xsd"
name="archetypeVersionExample">
<requiredProperties>
...
<requiredProperty key="archetypeVersion">
<defaultValue>${version}</defaultValue>
</requiredProperty>
</requiredProperties>
...
</archetype-descriptor>
No extra plugins or user entry needed.

obtain the location of a jar that is a dependency in maven

I have a project that uses some legacy script for processing the source code. I cannot get rid of it, so I want to call it from maven.
the problem is that I need to pass as an argument the location of a jar file. I have listed this jar file as a dependency in my pom.xml. is there a way that I can pass the absolute location of the jar file to this script?
This isn't by any means ideal, but you could call your script from maven, and pass this in as a parameter:
${settings.localRepository}/<path to artifact>
where path to artifact is a path made up of the group id and artifact id you want. Example, if you wanted a reference to the maven-jar-plugin version 2.2, you'd use this:
${settings.localRepository}/org/apache/maven/plugins/maven-jar-plugin/2.2/maven-jar-plugin-2.2.jar
I like Pascal Thivent's answer to a similar question better. You can refer to dependencies with the ${maven.dependency.junit.junit.jar.path} notation. Pascal includes a sample pom in his answer:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>q2359872</artifactId>
<version>1.0-SNAPSHOT</version>
<name>q2359872</name>
<properties>
<my.lib>${maven.dependency.junit.junit.jar.path}</my.lib>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<tasks>
<echo>${my.lib}</echo>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

Resources