I am currently working on a multi-module maven project. It has the following plugin :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<useDefaultDelimiters>false</useDefaultDelimiters>
<delimiters>
<delimiter>${*}</delimiter>
<delimiter>##</delimiter>
</delimiters>
</configuration>
</plugin>
From Maven documentation it is not very clear what this is exactly trying to do. Can someone please help me understand this.
If you also define resource sets to be filtered, placeholders marked with these delimiters will be replaced by their respective property values.
That means if you configure the main resources to be filtered:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
And you have a file src/main/resources/test.txt with this content:
The current project version is ##project.version##
Then this file will be filtered and created in target/classes/test.txt with this content:
The current project version is 1.0-SNAPSHOT
The default delimiters allow to mark placeholders with ${key} or #key#, your example changes this to ${key} and ##key##.
Also check https://maven.apache.org/plugins/maven-resources-plugin/resources-mojo.html#useDefaultDelimiters for further details.
Related
I have a maven project, which generates a jar file as a web project. Based on Maven I include a standalone Tomcat. Inside of the jar file, there is actually the war-file, which contains my application.
This application contains a "version.txt" in src/main/config (or any similar path), that is finally included in the war-file.
This version.txt looks like:
version: ${project.version}
I would like, that maven should replace the variable with the correct version from pom.xml.
In my pom.xml I have included:
<build>
<resources>
<resource>
<directory>src/main/config</directory>
<filtering>true</filtering>
<includes>
<include>**/version.txt</include>
</includes>
</resource>
<resource>
<resources>
</build>
So is there any way to include this version.txt and a working replacement in a war-file, which is in a (Tomcat)jar-file?
Addendum:
My File hierarchy looks like:
jar-file
-- ...
--war-file
---- ...
----version.txt
I suggest you use the maven-war-plugin.
https://maven.apache.org/plugins/maven-war-plugin/usage.html
It will expect a certain directory layout, and in the examples it clearly shows how to filter (replace maven variables into the web resources)
https://maven.apache.org/plugins/maven-war-plugin/examples/adding-filtering-webresources.html
If this solution falls short, then a more specific question based on this should should be asked later.
Thanks for the advice. No, there was no maven-war-plugin, but I have included it and based on the instructions, it works.
Short solution:
Added a resourceDirectory on same level like pom.xml and included version.txt
Added in pom.xml and activate filtering:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.1</version>
<configuration>
<webResources>
<resource>
<filtering>true</filtering>
<directory>externalresources</directory>
</resource>
</webResources>
</configuration>
</plugin>
I'm trying to build an rpm install with rpm-maven-plugin. In addition, I'm also trying to edit my post install script in order to use some Maven properties. For that reason, I'm using maven-resources plugin.
I'm following the answers in this post but it just doesn't work for me and the files aren't filtered and saved in the target directory.
My projects structure :
-my-app
-pom.xml
-app module
-src/..
-pom.xml
-rpm module
-pom.xml
-src/main/
-resources
-scripts
-post-install.sh
In the rpm module pom.xml I have the following two plugins :
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<resources>
<resource>
<directory>src/main/scripts/</directory>
<filtering>true</filtering>
<includes>
<include>post-install.sh</include>
</includes>
</resource>
</configuration>
</plugin>
and also :
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<extensions>true</extensions>
<configuration>
.......
<postinstallScriptlet>
<scriptFile>${basedir}/target/classes/post-install.sh</scriptFile>
<fileEncoding>utf-8</fileEncoding>
</postinstallScriptlet>
When I run mvn package I'm getting the following error :
[ERROR] Failed to execute goal org.codehaus.mojo:rpm-maven-plugin:2.2.0:rpm (default-rpm) on project my-app-package: Execution default-rpm of goal org.codehaus.mojo:rpm-maven-plugin:2.2.0:rpm failed: Invalid scriptlet declaration found - defined scriptFile does not exist: /root/my-app/rpm/target/classes/post-install.sh -> [Help 1]
I also tried to change the value of the include tag to **/post-install.sh but it didn't work.
To replace values in a file with values set in another file with maven this is a good way:
<!-- path to the final location of the resulting modified file - your output -->
<properties>
<filesPath>/Users/.../config/files</filesPath>
</properties>
<build>
<resources>
<resource>
<!-- the file to be modified. Here the name of the values to be changed in the properties file need to be added as variable names, e.g. ${varName} -->
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<!-- the file name or file types to be edited/updated -->
<include>*.xml</include>
</includes>
<!-- the target path is the location where the generated/edited resulting files should be saved. The default is `target/classes/` -->
<targetPath>${jdbcConfigFilesPath}</targetPath>
</resource>
</resources>
<filters>
<!-- the file where the variable values will be updated -->
<filter>file.properties</filter>
</filters>
</build>
This configuration will replace values in files from values set in a properties file.
If one wants to just set the values or the variables to be updated as properties in the pom.xml, one can just use the <properties> <yourVar>someValue</yourVar> </properties>option in the pom.xml instead of the
<filters>
<!-- the file where the variable values will be updated -->
<filter>file.properties</filter>
</filters>
Maven version: 3.5.4
My web directory is not in the standard location. It is in /web
Maven War config
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<webResources>
<!--
Filter these files to look for ${my.maven.property} to replace them
at build time with a maven property value
-->
<resource>
<filtering>true</filtering>
<directory>web/WEB-INF</directory>
<includes>
<include>**/web.xml</include>
</includes>
</resource>
</webResources>
<warSourceDirectory>web</warSourceDirectory>
<failOnMissingWebXml>true</failOnMissingWebXml>
<webXml>web/WEB-INF/web.xml</webXml>
<packagingExcludes>
${exclude.files.on.build}
</packagingExcludes>
</configuration>
</plugin>
properties snippet from pom.xml
<properties>
...
<!-- web.xml vars -->
<web.session.cookie.secure>true</web.session.cookie.secure> <!-- session cookie only sent over https -->
...
</properties>
web.xml snippet
<cookie-config>
...
<secure>${web.session.cookie.secure}</secure>
...
</cookie-config>
The property "${web.session.cookie.secure}" is not being replaced in the web.xml, and the property name is retained in the war file generated. I have not been able to pinpoint the configuration error. I am working in Intellij and get the same result whether I build the artifact off the intellij menu, or issue the mvn war:exploded command.
I am assuming that it may have something to do with the web directory location and a missing configuration item. The maven build runs as expected other than the issue with the properties not being replaced in the output.
Any ideas as to why the replacements would not be taking place using the filtering of the maven-war-plugin?
The maven-war-plugin uses ${basedir} as the location of the pom, so the target directory for filtering should be referenced via relative path from there.
<resource>
<filtering>true</filtering>
<directory>${basedir}/web/WEB-INF</directory>
<includes>
<include>**/web.xml</include>
</includes>
</resource>
The actuall path could be examined in mvn help:effective-pom.
My situation is:
I have a Maven project, I have my java classes in /app/src/main/java, my resources in /app/src/main/resources and my webapp files in /app/src/main/webapp
I have a javascript file in /common/script.js
Now what I want is to include (copy) the javascript file to the war file during the build phase of maven. To be precise, I want the script.js to land in /js/ directory of the war archive, just as it was placed in /app/src/main/webapp/js before starting the build.
I need this to share one version of resource files among many web-apps.
Kind regards,
Q.
You could do something like this, as documented here.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>../common</directory>
<targetPath>/js</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
You can use the mojo copy-resources to copy resources which are not in the default maven layout or not declared in the build/resources element.
Check
"maven-resources-plugin"
You can use maven-resources plugin to copy a file to the desired location. Before or after a war has been built
I'm creating a Maven archetype which generates a project skeleton that
will include a dependency on the project from which the archetype
originated.
For example, the origin project looks like:
origin/archetype/... archetype for generating project
/core/... core services
/extra/... extra services
and the archetype will generate a project with a POM that contains
dependencies like so:
<dependencies>
<dependency>
<groupId>com.foo</groupId>
<artifactId>origin-core</artifactId>
<version>SOMEVERSION</code>
</dependency>
</dependencies>
I want SOMEVERSION to be the version of the origin project at the time
that the archetype is built and installed into the repository.
So if the origin project is at version 1.0-SNAPSHOT and is mvn
installed, then I want the archetype to generate a dependency on
origin-core 1.0-SNAPSHOT. And when the origin project is released, and automatically
bumped to version 1.0, I want the archetype to generate a dependency on
origin-core 1.0.
Basically I'd like to use ${archetypeVersion} as a Velocity variable in the archetype
POM, but that doesn't seem possible.
Is there any other way of accomplishing what I'm trying to do here?
I asked the above question on the Maven mailing list a few days ago and got tumbleweeds. Fortunately, I eventually figured it out on my own. Here's at least one sane way to accomplish this:
Use Maven filtering on your src/main/resources/archetype-resources/pom.xml file to substitute in the current project version when building the archetype.
Here's how that's done:
Modify your archetype/pom.xml file to enable filtering on the archetype-resources/pom.xml file and not on anything else (because your archetype files will naturally have ${variable}s all over the place and you don't want those to be substituted at build time, you want them to be substituted when the archetype is created).
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>archetype-resources/pom.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>archetype-resources/pom.xml</exclude>
</excludes>
</resource>
</resources>
Enable an escape character for use when filtering, so that you can escape all the variables in your archetype pom that need to remain as-is so that they can be substituted at archetype generation time:
<pluginManagement>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<escapeString>\</escapeString>
</configuration>
</plugin>
</plugins>
</pluginManagement>
(Note the <resources> and <pluginManagement> elements shown above should be placed inside the <build> element of your POM.)
Use ${project.version} in your archetype pom, where you want the version of your archetype project to be inserted, and escape all of the other variables that should remain unsubstituted until archetype generation time:
<?xml version="1.0" encoding="UTF-8"?>
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>\${groupId}</groupId>
<artifactId>\${artifactId}</artifactId>
<version>\${version}</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.foo</groupId>
<artifactId>origin-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
An alternative solution to the accepted answer is to filter a default property in the archetype's descriptor/metadata file
This is done like so:
The maven filtering only filters this file:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>META-INF/maven/archetype-metadata.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>META-INF/maven/archetype-metadata.xml</exclude>
</excludes>
</resource>
</resources>
The archetype meta data file:
<archetype-descriptor ...>
<requiredProperties>
<requiredProperty key="projectVersion">
<defaultValue>${project.version}</defaultValue>
</requiredProperty>
</requiredProperties>
...
</archetype-descriptor>
and the archetype's POM would be similar to before except that it would use the projectVersion required property value as the project version:
<?xml version="1.0" encoding="UTF-8"?>
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<version>${version}</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.foo</groupId>
<artifactId>origin-core</artifactId>
<version>${projectVersion}</version>
</dependency>
</dependencies>
</project>
This approach has the advantage that it avoids having to escape all the property values in the archetype's POM and the resource plugin configuration that goes with it. Personally, I find all of that quite ugly and error prone.
It does mean that the user is asked to confirm or alter the project version when generating the archetype. Depending on the scenario, I guess this could be considered a good or a bad thing.
I tried something rather stupid and it seems to have worked. I added the following to my META-INF/maven/archetype-metadata.xml file:
<requiredProperties>
<requiredProperty key="archetypeVersion"> </requiredProperty>
</requiredProperties>
You would think it would know about it by default but it doesn't so this seems to remind it to use it. Perhaps it is due to a bug in maven.
#samskivert's solution is great, but I searched an alternative to the ugly escaping \$.
So I configured a different delimiter for the maven-resources-plugin, hoping its easier to maintain.
My delimiter is #archetypeProperty{*} and my archetype-resources/pom.xml becomes:
<?xml version="1.0" encoding="UTF-8"?>
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<version>#archetypeProperty{revision}</version>
[...]
</project>
I configured this delimiter in my archetype/pom.xml's pluginManagement section and disabled default delimiters:
<properties>
<revision>1.0</revision>
[...]
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>archetype-resources/pom.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>archetype-resources/pom.xml</exclude>
</excludes>
</resource>
</resources>
[...]
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<useDefaultDelimiters>false</useDefaultDelimiters>
<delimiters>
<delimiter>#archetypeProperty{*}</delimiter>
</delimiters>
</configuration>
</plugin>
[...]
</plugins>
</pluginManagement>
</build>