Order of resource directories in Maven - maven-3

I would like to have my Java project using Maven set up so that when developing locally and when running unit tests, resources are taken from the standard src/main/resources and src/test/resources directories, while when applying a profile the resources are overwritten with deployment-specific ones. Ideally, the profile specific resources will be a subset of the full resources, so the process should work by first writing the regular resources, then applying the profile specific ones on top of the first.
My directory layout is the standard one, with the profiles resources under src/main/env/{profile}.
I managed to do this using multiple stanzas under build/resources:
<profiles>
<profile>
<id>dev</id>
<activation><activeByDefault>true</activeByDefault></activation>
<properties>
<targetEnv>dev</targetEnv>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<targetEnv>test</targetEnv>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<targetEnv>prod</targetEnv>
</properties>
</profile>
</profiles>
<build>
<resources>
<resource>
<directory>src/main/env/${targetEnv}</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<build>
This is working, however, my first attempt was with the two resource directories ordered in the opposite way (first the regular directory, the the profile specific one), in a way to match the overwriting process. Instead, it was overwriting the profile specific files with the regular ones.
Does Maven guarantee an order for the stanzas under build/resources at all?

Related

How to include/exclude resources in maven war package

Within my MAVEN project I'm trying to build a war package with certain resources based on a profile (defined in my settings.xml).
pom.xml:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<!-- archiveClasses>true</archiveClasses Enable this line will remove compiled classes from package -->
<!-- packagingExcludes>view/test/**,WEB-INF/classes/**</packagingExcludes Does not work -->
<packagingExcludes>view/test/**</packagingExcludes>
<webResources>
<resource>
<directory>src/main/webapp/</directory>
<filtering>false</filtering>
<includes>
<include>**/**</include>
</includes>
</resource>
<resource>
<directory>resources/</directory>
<targetPath>WEB-INF/classes</targetPath>
<filtering>false</filtering>
<!-- excludes><exclude>**</exclude></excludes Does not work -->
<includes>
<include>ehcache.xml</include>
<include>${include.files}</include>
</includes>
</resource>
</webResources>
<includeEmptyDirectories>true</includeEmptyDirectories>
</configuration>
</plugin>
My src/main/resources folder is empty, so in my package there are no config files that are not expected. But when I move my resources folder into src/main/resources then the profiles are not working anymore and the package always contains all files from the resources folder.
How to alter my pom.xml so that resources folder can be moved into src/main/resources as to my understanding that is where you store resources like configuration files etc ('best-practice')?
See if you can reorganize your resources in a way so that you can apply a filter to the resources and that most files are always present for every configuration.
Suppose you have a properties file that need different values for different configurations. You can substitute the value with a variable like this:
url=${url}
mode=${mode}
Now you can use profiles to set the values for the files that need to be filtered and the ones that need to be excluded entirely for that configuration:
<profile>
<id>production</id>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>[non-resource file #1]</exclude>
<exclude>[non-resource file #2]</exclude>
<exclude>[non-resource file #3]</exclude>
</excludes>
</resource>
</resources>
</build>
<properties>
<url>www.something.com</url>
<mode>production</mode>
</properties>
</profile>
<profile>
<id>development</id>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>[non-resource file #1]</exclude>
<exclude>[non-resource file #2]</exclude>
<exclude>[non-resource file #3]</exclude>
</excludes>
</resource>
</resources>
</build>
<properties>
<url>localhost:8080/something</url>
<mode>development</mode>
</properties>
</profile>
Finally you can delete the webResources tag in your maven-war-plugin. It wil pick up src/main/resources now because it's a configured resource.

Fortify + maven exclude xsd files

I have an issue with running scan with excluding xsd files in fortify SCA.
I am using maven (with fortify plugin) + jenkins.
My POM.xml used by Jenkins:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pl.bluecode</groupId>
<artifactId>bc</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<properties>
</properties>
<scm>
<connection>scm:svn:https://subversion......</connection>
<developerConnection>scm:svn:https://subversion.....</developerConnection>
<tag>HEAD</tag>
<url>https://subversion......</url>
</scm>
<profiles>
<profile>
<id>common</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>!skipCommonProfile</name>
</property>
</activation>
<modules>
<module>Project1</module>
<module>Project2</module>
</modules>
</profile>
<profile>
<id>profile1</id>
<modules>
<module>Project3</module>
<module>Project4</module>
</modules>
</profile>
</profiles>
<build>
<sourceDirectory>${basedir}/src</sourceDirectory>
<finalName>${project.artifactId}</finalName>
<resources>
<resource>
<directory>${basedir}/src</directory>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>${basedir}/src</directory>
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.fortify.ps.maven.plugin</groupId>
<artifactId>maven-sca-plugin</artifactId>
<version>2.6</version>
<configuration>
<source>1.5</source>
<failOnSCAError>true</failOnSCAError>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
My Jenkins Maven goals looks like:
1st goal:
com.fortify.ps.maven.plugin:maven-sca-plugin:2.6:clean -Pprofile1
2nd goal:
com.fortify.ps.maven.plugin:maven-sca-plugin:2.6:translate -Pprofile1
3rd goal:
com.fortify.ps.maven.plugin:maven-sca-plugin:2.6:scan -Pprofile1
Unfortunately I can not attach image.
Above configuration is working as expected till now.
Now, I'd like to exclude all XSD files from scan.
How to do it?
I tried to add -exclude ".xsd" entry in maven goals:
com.fortify.ps.maven.plugin:maven-sca-plugin:2.6:scan -Pprofile -exclude ".xsd"
but it doesn't work.
If someone can help we I would be grateful.
Thanks.
in theory the Fortify Maven Plugin supports the exclusion of files, but it doesn't always work as expected.
Now, that being said, you are not invoking the exclusion correctly. Where you built the Fortify Maven Plugin, find the documentation for the translate goal, e.g. for me: /Samples/advanced/maven-plugin/target/site/translate-mojo.html#exclude.
There you can find the correct way to invoke exclusion. On the command line:
"-Dfortify.sca.exclude=*.xsd"
or in the POM (if you set up the fortify translate job there)
<exclude>
*.xsd
</exclude>
Now back to my first point. Sometimes exclusion is more difficult to effect than just by setting the value as *.extension. You may also need to specify the directory as well, so if the above doesn't work, try also the Fortify special glob parameter "**" which means any recursive subdirectory match. To wit:
"-Dfortify.sca.exclude=**/*.xsd"
or
<exclude>
**/*.xsd
</exclude>
If neither of the above work, then contact Fortify Technical Support.
Pro tip: you can also set this value in Core/config/fortify-sca.properties, where it will affect every invocation of sourceanalyzer on the system. That includes invocations via the maven plugin.

In multimodule maven project, how to execute proper goal for each module?

I have three maven projects in my prototype:
bookman (main project)
|-- bookman-back-lend (module, simple service app)
\-- bookman-front-web (module, simple web app)
This is very simple example book lending app (for library or something) to learn various technologies and all of that.
Problem is that I can't make parent pom to execute goals in module poms.
Calling mvn clean package wildfly:deploy in any module individually works without problem. It compiles, deploys, war is replaced, Wildfly 8 does its thing, etc. But if I call parent POM with mvn clean package (I'm not even sure what to call...), it doesn't do much - certainly it does not deploy to wildfly any of modules. Wildfly does not budge. In parent POM, calling mvn clean package wildfly:deploy does not work, of course.
Here is parent pom.xml:
<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>org.mader.bookman</groupId>
<artifactId>bookman</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Main BookMan superproject.</name>
<description>Main BookMan superproject.</description>
<modules>
<module>bookman-front-web</module>
<module>bookman-back-lend</module>
</modules>
</project>
And module POMs, with some stuff cut out for brevity (I assume they aren't related to my problem).
bookman-front-web/pom.xml:
<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>
<artifactId>bookman-front-web</artifactId>
<packaging>war</packaging>
<name>Frontend project - webpage.</name>
<description>Web page to handle lending books.</description>
<parent>
<groupId>org.mader.bookman</groupId>
<artifactId>bookman</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<properties>
...
</properties>
<repositories>
...
</repositories>
<dependencyManagement>
...
</dependencyManagement>
<dependencies>
...
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<defaultGoal>clean package wildfly:deploy</defaultGoal>
<plugins>
<plugin> <!-- To use, run: mvn clean package wildfly:deploy -->
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>${version.wildfly.maven.plugin}</version>
</plugin>
</plugins>
</build>
</project>
And bookman-back-lend/pom.xml:
<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>
<artifactId>bookman-back-lend</artifactId>
<packaging>war</packaging>
<name>Backend project - lending.</name>
<description>Business logic to handle books, users and act of lending.</description>
<parent>
<groupId>org.mader.bookman</groupId>
<artifactId>bookman</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<properties>
...
</properties>
<repositories>
...
</repositories>
<dependencyManagement>
...
</dependencyManagement>
<dependencies>
...
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<defaultGoal>clean package wildfly:deploy</defaultGoal>
<plugins>
<plugin> <!-- To use, run: mvn clean package wildfly:deploy -->
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>${version.wildfly.maven.plugin}</version>
</plugin>
</plugins>
</build>
</project>
It should be possible to have customized goals to execute for each module individually, right? Right? Otherwise those aggregate POMs are rather useless.
Unfortunately, questions like this suggest that maven goal executed on parent POM is exactly same goal to execute on child POMs. Who thinks up something like that? What if I need completely different goals in each child module?
All answers I found are few years old, maybe... just maybe... sanity prevailed and maven now allows something like that? After all, all information neccessary to do this should be accessible, like defaultGoal tag.
Problem was solved in radical way. Maven is dead, long live Gradle.
I was tinkering with it last few days and I already moved prototype to point where it actually works. While there is still tons of work left, I already know I will not be looking back.
So, yeah... if you have requirements that cannot be done easily or at all with Maven for various reasons, then consider Gradle. In fact, consider Gradle anyway.

How to override Maven 3.0 parent profile properties from child pom?

How to override Maven 3.0 parent profile properties from child pom?
I want to be override profile properties from a parent pom. I've used help:effective-pom -Pjmeter and can see that the child properties are not being picked up and tried many various permutations all without success. I expect the parents properties to be overridden by the child properties.
Parent pom profile:
<profile>
<id>jmeter</id>
<properties combine.self="override">
<maven.jmeter.phase>verify</maven.jmeter.phase>
<maven.jmeter.goal>jmeter</maven.jmeter.goal>
<!-- We use the ${basedir} to avoid NullPointer errors when src/test/jmeter doesn't exist -->
<!-- when running jmeter test the default to set in the child pom is ${basedir}/src/test/jmeter -->
<maven.jmeter.testFilesDirectory>${basedir}</maven.jmeter.testFilesDirectory>
<maven.jmeter.jMeterTestFile>**/*.jmx</maven.jmeter.jMeterTestFile>
<maven.jmeter.excludeJmeterTestFile>NOT_NULL</maven.jmeter.excludeJmeterTestFile>
<maven.jmeter.testResultsTimestamp>false</maven.jmeter.testResultsTimestamp>
<maven.jmeter.server>localhost</maven.jmeter.server>
<maven.jmeter.port>8080</maven.jmeter.port>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>${jmeter.version}</version>
<executions>
<execution>
<id>jmeter-tests</id>
<phase>${maven.jmeter.phase}</phase>
<goals>
<goal>${maven.jmeter.goal}</goal>
</goals>
<configuration>
<testFilesDirectory>${maven.jmeter.testFilesDirectory}</testFilesDirectory>
<testFilesIncluded>
<jMeterTestFile>${maven.jmeter.jMeterTestFile}</jMeterTestFile>
</testFilesIncluded>
<testFilesExcluded>
<excludeJmeterTestFile>${maven.jmeter.excludeJmeterTestFile}</excludeJmeterTestFile>
</testFilesExcluded>
<testResultsTimestamp>${maven.jmeter.testResultsTimestamp}</testResultsTimestamp>
<propertiesUser>
<!-- server and port must be defined (and used) in the JMeter jmx file as User Defined Variables
${__P(server,localhost)}
${__P(port,80)}
See http://jmeter.apache.org/usermanual/component_reference.html#User_Defined_Variables
http://jmeter.apache.org/usermanual/test_plan.html#using_variables
http://jmeter.apache.org/usermanual/functions.html#__P
http://jmeter.apache.org/usermanual/best-practices.html#parameterising_tests
-->
<server>${maven.jmeter.server}</server>
<port>${maven.jmeter.port}</port>
</propertiesUser>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
and then in the child pom:
<profile>
<id>jmeter</id>
<activation><activeByDefault>false</activeByDefault></activation>
<properties>
<maven.jmeter.testFilesDirectory>${project.basedir}/src/test/jmeter</maven.jmeter.testFilesDirectory>
<!-- csv based JMeter tests result in one graph in Jenkins, we want a graph per test -->
<maven.jmeter.excludeJmeterTestFile>**/KRAD.jmx</maven.jmeter.excludeJmeterTestFile>
</properties>
</profile>
I'm not sure properties are overridden that way. Either way, the plugin will not run as you have it, since you only define <pluginManagement> and no straight direct <plugins> child under <build>. If you don't want your plugin to run in the parent, just define the <plugins> tags in the children where you do want this running as such:
<profile>
<id>jmeter</id>
<activation><activeByDefault>false</activeByDefault></activation>
<build>
<plugins>
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<configuration>
<testFilesDirectory>${maven.jmeter.jMeterTestFile}</testFilesDirectory>
<!-- csv based JMeter tests result in one graph in Jenkins, we want a graph per test -->
<testFilesExcluded>
<excludeJmeterTestFile>${maven.jmeter.excludeJmeterTestFile}</excludeJmeterTestFile>
</testFilesExcluded>
</configuration>
</plugin>
</plugins>
</build>
</profile>
Hope this helps.

Sonar and MAVEN POM file with Dependencies

I have setup Maven and Sonar to analyze .NET projects and it works fine for winforms projects. However when I add an MVC project it gives a build Failure because it can't find the System.Web.MVC.dll file. I have an Fx-Cop plugin that runs as part of Sonar.
One way to get around this would be to package the dll, copy local= true with the project. However I dont want to do that(any thing wrong with packaging the MVC file along?)
How do I add a dependency to the MVC dll? I followed this example and added it like this:
<dependencies>
<dependency>
<groupId>artifact_group_id</groupId>
<artifactId>System.WEb.MVC</artifactId>
<version>4.0.30319</version>
<type>library</type>
<scope>system</scope>
<systemPath>C:\DOTNET\DLLS\System.Web.Mvc.dll</systemPath>
</dependency>
</dependencies>
Still I get a Build Failure caused by FX-Cop. Looking at the FX-Cop logs I get a message as below:
The following error was encountered while reading module 'MyTestMvcApp': Assembly reference cannot be resolved: System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
I'm using apache-maven-3.0.2 and sonar-3.2. Can anyone help with this?
This is the full POM.XML file
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Test</groupId>
<artifactId>Sonar.For.NET.Test</artifactId>
<version>1.0</version>
<name>Testing </name>
<packaging>netpack</packaging>
<properties>
<visual.studio.solution>TestProjectsForSonarBuild.sln</visual.studio.solution>
<visual.test.project.pattern>*.Tests;*Test</visual.test.project.pattern>
<dotnet.tool.version>4.0</dotnet.tool.version>
<sonar.language>cs</sonar.language>
</properties>
<dependencies>
<dependency>
<groupId>artifact_group_id</groupId>
<artifactId>System.WEb.MVC</artifactId>
<version>4.0.30319</version>
<type>library</type>
<scope>system</scope>
<systemPath>C:\DOTNET\DLLS\System.Web.Mvc.dll</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.sonar-plugins.dotnet</groupId>
<artifactId>maven-dotnet-plugin</artifactId>
<version>0.6</version>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<configuration>
<toolVersion>3.5</toolVersion>
<buildConfigurations>Debug</buildConfigurations>
<rebuild>true</rebuild>
<language>cs</language>
</configuration>
</plugin>
</plugins>
</build>
</project>
Thanks for your time.
You can use the "sonar.fxcop.assemblyDependencyDirectories" property as described on the documentation page for the FxCop plugin.
So you have 2 solutions from there:
either your build process copies "System.Web.MVC.dll" in a temp folder, which you reference through the this property
or you directly reference an absolute path where this DLL can be found (but your property may then be not portable accros different environments/servers)

Resources