Issue
Hello I'm trying to understand the filtering include/exclude in Maven as I am a Maven noob. I was looking up how to read the version from the pom file in JAVA and found the solution but I have a few questions about the filtering. I understand the filtering with include and/or exclude in the same resource block, but I'm not understanding what is happening when you include/exclude in different resource blocks of the same file/folder.
My folder structure with simplified RandomFolder and its contents:
src
├── main
│ ├── resources
│ ├── RandomFolder
│ ├──aFile.dll
│ ├──someFile.txt
│ └── pom.properties
pom.properties file contains:
version=${revision}
#1
This is how I currently have it (simplified) as a working solution. I understand it's filtering the pom.properties file and replacing '${revision}' with '1.0.0' aka 'version=1.0.0'. Would the pom.properties file be filtered (aka 'version=1.0.0') when mvn package
is ran and a jar file is generated? I would assume so, but wanted to make sure.
I also understand that typically you wouldn't specify the filename in the filtering and instead it would be **/*.properties
, but since this was the only properties file I think it's easier and cleaner to have the filename and it shouldn't cause any issues (let me know if I am wrong on this assumption).
...
<properties>
<revision>1.0.0</revision>
</properties>
...
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/pom.properties</include>
</includes>
</resource>
</resources>
...
</build>
#2
I believe this is the way tutorial websites would normally represent include and exclude in a resource block. Really unnecessary in this example as it filters everything besides the pom.properties (found and tested that the excludes block overwrites the includes block no matter the order).
No question here. Just wanted to state that I know about this approach.
...
<properties>
<revision>1.0.0</revision>
</properties>
...
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/pom.properties</include>
</includes>
<excludes>
<exclude>**/pom.properties</exclude>
</excludes>
</resource>
</resources>
...
</build>
#3
Why does this work? I would assume its filtering the file first so that the file reads '1.0.0' then is not filtering, but I want to make sure. This stems from a similar solution I found to get the pom version (see #5 further down). I tested this and it filters the pom.properties file.
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/pom.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/pom.properties</exclude>
</excludes>
</resource>
</resources>
...
</build>
#4
The flip flop of #2 with the exclude block before the include block, which seems kinda unnecessary. I would assume its not filtering the file first then filtering the file so that the file reads '1.0.0', but I want to make sure. I tested this and it filters the pom.properties file.
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/pom.properties</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/pom.properties</include>
</includes>
</resource>
</resources>
...
</build>
#5
This I don't really know. This was a top solution found for: Maven resource filtering exclude
And the link provided in that solution I feel doesn't explain the reasoning for its' solution: https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
So is it filtering everything except the pom.properties file but then not filter everything including the pom.properties file? Why? What's the purpose of this? Are they both the same thing? Or a double negative? Does it impact what appears in the build/package?
This 'solution' did not filter the pom.properties file when I tested it.
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>**/pom.properties</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/pom.properties</include>
</includes>
</resource>
</resources>
...
</build>
Please let me know if you need additional information. I would really appreciate it if you can go through each section (#1 to #5) and answer them. Thank you in advance!
Solution
Robert Scholte's response helped me understand that filtering also copied over files. This is something I did not understand before as I thought it was just modifying the file(s) in the desired folder(s).
With additional help with understanding exclusions from: http://www.avajava.com/tutorials/lessons/how-do-i-exclude-particular-resources-from-being-processed.html
I was able to answer my questions.
#1. Still not sure, but I believe the pom.properties file would be filtered in jar.
#2. N/A. No question to answer.
#3. For #3, #4, #5 I created a test.properties in same folder as pom.properties and contains the same contents.
Testing required me to use command: mvn clean install -DskipTests
to visually see the differences between #3, #4 and #5.
This would be the result after creating the test.properties file and running the above command (without the block in pom file) for a visual reference:
src
├── main
│ ├── resources
│ ├── RandomFolder
│ ├──aFile.dll
│ ├──someFile.txt
│ └── pom.properties
target
├── classes
│ ├── MultipleGeneratedFolders
│ ├── RandomFolder
│ ├──aFile.dll
│ ├──someFile.txt
│ ├── pom.properties
│ └── test.properties
So for #3, it filtered only the pom.properties and moved to a '/target/classes/' path (same level as 'src'). But because of the second resource block, it copies over all the contents in the RandomFolder and the test.properties file to '/target/classes/' path without filtering them!
#4. Exact same result as #3. Everything is copied over '/target/classes/', but only pom.properties file is filtered.
#5. Here is the interesting one. The first resource block with filtering true and excluding pom.properties is filtering everything (since there is no , it defaults to everything) and then copies to '/target/classes/' path. So this means the test.properties file gets filtered! The second resource block with filtering false and including pom.properties is not filtering the pom.properties file (so it leaves as raw text) then copies over to '/target/classes/' path. Basically, everything besides pom.properties gets filtered and copied over to '/target/classes/' path.
Summary of Conclusions
In short, filtering refers to replacing the variables in files with the properties block in the pom file, such as ${revision}
. Filtering does not require or (if neither are specified it defaults to including all files) and copies selected files to the target folder.
If you filter (set to TRUE) and only a specific pattern or file, it will only filter the selected files and copy them to the target folder. If you filter (set to TRUE) and only , it will filter everything except for the specified pattern or file and copy only the filtered files to the target folder.
If you don't filter (set to FALSE) and only a specific pattern or file, it will only copy the selected files to the target folder without filtering them. If you don't filter (set to FALSE) and only a specific pattern or file, it will copy all files except the selected files to the target folder without filtering them.
(I could be wrong in my conclusions so take it may not be completely accurate, but 'good enough for government work' as they say)
Solution
You can run mvn process-resources -X
to see more details about which files are copied.
But this is how it works:
per resource-block the fileset to copy is selected by choosing all includes
(default is all), minus all excludes
(default none).
If filtering is set to true, the placehoders in these files will be replaced, otherwise they will be copied as is.
Answered By - Robert Scholte
Answer Checked By - Cary Denson (JavaFixing Admin)