Maven exclude resources not working as expected - maven

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)

Related

How to acces POM project name from properties file

I have logback.properties file which contains the following properties.
#logging
logging.server=
logging.port=
logging.path=/opt/${project.name}/logs
Inside my POM file I've got the <name> tag, which specifies the project name. I'd like to inject this name in few properties files like the lockback one above. Doing the above results in creating a folder called project.name_IS_UNDEFINED. Is it possible to access the project name and how?
UPDATE
Ralph gave the correct answer, however check my comment, because for spring boot applications you need to used %project.name% instead of ${project.name}!
You need to transfer the properties defined in you maven compile-time script into the application at run time.
The most easiest way is to use maven's resource filtering (the name is a bit misleading, it is not a filter that selects files, it is a property replace for text/resource files) in order to let maven replace ${project.name} in you logback.properties file.
true
${basedir}/src/main/resources
If you want enabling resource filtering just for one file (and not for the others to prevent maven from replacing other markers then you can use this snippet:
<resources>
<!-- enable filtering for logback.properties only -->
<resource>
<filtering>false</filtering>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
<excludes>
<exclude>WHEREVER_LOCATED/logback.properties</exclude>
</excludes>
</resource>
<resource>
<filtering>true</filtering>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>WHEREVER_LOCATED/logback.properties</include>
</includes>
</resource>
</resources>
Try with the resource filtering:
https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html

How to copy directory using maven copy resoures plugin

I have referred the maven documentation here https://maven.apache.org/plugins/maven-resources-plugin/examples/include-exclude.html to understand about including whatever the files we need. But it has mentioned only about including files. So how can I copy all the directories and files inside a specific directory using maven resources plug-in?
Try without specifying any includes and excludes so that it picks all directories and files inside the resources directory.
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>

Excluding Resource while packaging in maven

I have a project with sample structure as :
jcr_root
|_apps
|_A
|_B
|_etc
|_A
|_B
What I need to do is while creating a package, I need to include either "apps/A & etc/A" or "apps/B & etc/B"
In my pom.xml, I tried something like :
<resources>
<resource>
<directory>src/main/content/jcr_root</directory>
<excludes>
<exclude>apps/A/**</exclude>
<exclude>etc/A/**</exclude>
</excludes>
</resource>
</resources>
But still both 'A' and 'B' under apps and etc get included while packaging. I'm using content-package-maven-plugin to build a package that would be deployed on CQ.
I tried putting entries in filter.xml but then it is used while deployment and not while packaging.
It seems, the include/exclude tags are not at all working. For testing, I tried:
<resources>
<resource>
<directory>src/main/content/jcr_root</directory>
<excludes>
<exclude>**/*.otf</exclude>
</excludes>
</resource>
</resources>
But still fonts.otf file was getting included in the packaged zip.
Some help or hints please. Let me know if any more info is required.
Many Thanks in Advance.
So finally I was able to create a package with the excluded resources.
The issue was not with the include/exclude tag(they always worked fine.)
The files after excluding some resource were copied to "target/classes" directory
Issue was that the maven-content-package plugin took the resource to package from original source directory rather than the "target/classes" directory created.Thus it always included everything. This is the default behaviour of maven-content-package plugin.
Thus I had to explicitly tell the plugin that you need to pick the resource to package from "target/classes".
<builtContentDirectory>${basedir}/target/classes</builtContentDirectory>
Please let me know if anyone needs more detail. Thanks for all your answers:)
Since you want to include jcr_root/app/A and jcr_root/etc/A
Please you try using this in POM.xml:
<project>
...
<resources>
<resource>
<directory>jcr_root</directory>
<includes>
<include>**/*A*</include>
</includes>
<excludes>
<exclude>**/*B*</exclude>
</excludes>
</resource>
<resources>
</project>
Similarly you can do it for getting jcr_root/app/B and jcr_root/etc/B.
Regards
Jyotsna

Maven project.build.directory

In Maven, what does the project.build.directory refer to? I am a bit confused, does it reference the source code directory or the target directory in the Maven project?
You can find those maven properties in the super pom.
You find the jar here:
${M2_HOME}/lib/maven-model-builder-3.0.3.jar
Open the jar with 7-zip or some other archiver (or use the jar tool).
Navigate to
org/apache/maven/model
There you'll find the pom-4.0.0.xml.
It contains all those "short cuts":
<project>
...
<build>
<directory>${project.basedir}/target</directory>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<finalName>${project.artifactId}-${project.version}</finalName>
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
</testResource>
</testResources>
...
</build>
...
</project>
Update
After some lobbying I am adding a link to the pom-4.0.0.xml. This allows you to see the properties without opening up the local jar file.
It points to your top level output directory (which by default is target):
https://web.archive.org/web/20150527103929/http://docs.codehaus.org/display/MAVENUSER/MavenPropertiesGuide
EDIT: As has been pointed out, Codehaus is now sadly defunct. You can find details about these properties from Sonatype here:
http://books.sonatype.com/mvnref-book/reference/resource-filtering-sect-properties.html#resource-filtering-sect-project-properties
If you are ever trying to reference output directories in Maven, you should never use a literal value like target/classes. Instead you should use property references to refer to these directories.
project.build.sourceDirectory
project.build.scriptSourceDirectory
project.build.testSourceDirectory
project.build.outputDirectory
project.build.testOutputDirectory
project.build.directory
sourceDirectory, scriptSourceDirectory, and testSourceDirectory provide access to the source directories for the project. outputDirectory and testOutputDirectory provide access to the directories where Maven is going to put bytecode or other build output. directory refers to the directory which contains all of these output directories.
You can find the most up to date answer for the value in your project just execute the
mvn3 help:effective-pom
command and find the <build> ... <directory> tag's value in the result aka in the effective-pom. It will show the value of the Super POM unless you have overwritten.
Aside from #Verhás István answer (which I like), I was expecting a one-liner for the question:
${project.reporting.outputDirectory} resolves to target/site in your project.

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