Maven : Child pom's argline is not applied? - maven

I have a multi-module maven project. In the child module, failsafe plugin is used for the integration tests run. Some argLines are defined accordingly :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skipAfterFailureCount>1</skipAfterFailureCount>
<argLine>-Xmx2048M -Xss512M -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC</argLine>
</configuration>
</plugin>
The problem is when I run the tests as mvn test or mvn integration-test, the arglines are not applied for the tests from neither the parent pom directory nor the child pom directory, but if I run the tests as mvn failsafe:integration-test from both of the directories, the arglines param are applied.
What is the reason behind this ? Is there any way to apply those params when I run the tests with mvn test command ? I tried to pass the parameters via command line as mvn test -Dchild.argline="-Xmx2048M -Xss512M -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC"
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skipAfterFailureCount>1</skipAfterFailureCount>
<argLine>${child.argline}</argLine>
</configuration>
</plugin>
But it didn't work.
Also I tried to bind test and integration-test phases to failsafe integration-test and defined configuration params there, but it didn't work as well..
I set the MAVEN_OPTS accordingly but it didn't help...

The failsafe plugin goals are not included in the lifecycle by default. The POM configuration must include it. See this SO answer for an example. Also ensure that the plugin definition is in the <plugins> section, not inside a <pluginManagement> element.
As for how to define options in the POM - use the names supplied in the documentation. So, to specify argLine, add
<argLine>...</argLine>
in the plugin config. To specify on the command line, note that "User property" for the value you want to set. For the failsafe plugin's argLine, the user property is also argLine, so on the command line specify
-DargLine=...
Maven knows nothing about child.argline so silently ignores it. Also note, attribute and user property names are case sensitive.

Related

Can maven exec:java be used with an arbitrary java class from the command iine

We have a few java/scala classes with main methods that would be useful to run via mvn exec:java.
Is it possible to do so without specifying the classes in the pom.xml? The examples that I have seen look like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions><execution>
<goals><goal>java</goal></goals>
</execution></executions>
<configuration>
<mainClass>some.main.MyClass</mainClass>
</configuration>
</plugin>
And then get executed as:
mvn exec:java -Dexec.mainClass="some.main.MyClass"
The intent is to be able to run
mvn exec:java -Dexec.mainClass="some.other.main.OtherClass"
even though it were not specified in the pom.xml.
When attempting to run that the error is
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.6.0:java (default-cli) on project sentiment: An exception occured while executing the Java class. myapp.MyMain
In other words the class specified on the command line is ignored in favor of the one listed in the pom.xml.
The Documentation at https://www.mojohaus.org/exec-maven-plugin/usage.html
says:
If you want to execute Java programs in the same VM, you can either
use the command line version
mvn exec:java -Dexec.mainClass="com.example.Main" [-Dexec.args="argument1"]
This works without adding anything to your pom.
As written in the comment, this only works, if you don't have a configuration in your pom. If you do have a configuration in your pom, you can use a property in it, which can be overridden from the command line
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions><execution>
<goals><goal>java</goal></goals>
</execution></executions>
<configuration>
<mainClass>${my.mainClass}</mainClass>
</configuration>
</plugin>
and predefine the property (nested directly in <project>)
<properties>
<my.mainClass>some.main.MyClass</my.mainClass>
</properties>
then you can run with
mvn exec:java -Dmy.mainClass="aaa.Test"
Looking from your usage if you are using the -Dexec.mainClass everytime, i would suggest you can get rid of the mainClass in the plugin configuration. The benefit of defining the mainClass would be to run like : mvn exec:java & it picks the main class from your defined class in pom.xml.
Once you remove the mainClass from pom.xml, you should be able to use any mainClass in the maven exec plugin usage from command line.

How to add excludedGroups argument to maven command

i have 2 maven profiles in my parent/pom.xml file .
The first profile run only a certain group.
<configuration>
<groups>com.XXXXXXX.common.daily.util.UnitTest</groups>
</configuration>
the second profile one run all the tests.
I would like to use an argument on the maven command
in the second profile that will exclude
this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<groups>com.XXXXXX.common.daily.util.UnitTest</groups>
<skipTests>${skipFastTests}</skipTests>
</configuration>
</plugin>
i don't want to change the pom.xml for the second profile.
I want to know how to add additional parameter for excludedGroups ?
mvn test -P=profile2 ______
You can exclude a category in the plugin configuration in the pom file. But if you want to dynamically exclude a given group via the mvn command line, you can do so by using the 'excludedGroups' parameter like so:
mvn test -DexcludedGroups=com.group.ExcludedCategory
http://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#excludedGroups
in either surefire or failsafe, add
<excludedGroups>${excluded.tests}</excludedGroups>
and then define this variable excluded.tests to be the interface that is used in #Category to mark which tests to bypass.
finally, when running an excluded tests in command line, override this value. It seems you are excluding com.XXXXXX.common.daily.util.UnitTest. Either define it empty in your profile and override with that; or exclude by default but override with empty.

How to disable jar creation in commandline in a maven project?

I have a maven project for which I'm running two separate builds.
In one build I want to save the build time by disabling the jar creation of maven modules in it.(There are 45 maven modules). There is a Maven-Jar-Plugin that is being used to create the jars.
I want to conditionally disable the jar creation at the command line, that is, looking for something similar to -Dskiptests used to skip the unit tests though there is a surefire plugin by default.
The maven-jar-plugin does not provide any skip option.
However, several ways are possible to achieve your requirement.
You may just skip the phase which brings by default (via default mappings) the jar creation, that is, the package phase, and as such simply invoke
mvn clean test
The additional phases would not make sense if you do not create a jar file anyway: package, install, deploy would not have anything to process. Moreover, the additional integration phases may also be impacted depending on your strategy for integration tests, if any.
Alternatively, you can configure your pom as following:
<properties>
<jar.creation>package</jar.creation>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>default-jar</id>
<phase>${jar.creation}</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
As such, the default behavior would still provide a jar creation, while executing maven as following:
mvn clean install -Djar.creation=false
Would instead skip the creation of the jar.
What we are actually doing:
We are re-defining the default execution of the maven-jar-plugin
We are overriding its execution id, as such getting more control over it
We are placing its execution phase binding to a configurable (via property) phase
Default phase (property value) keeps on being package
At command line time you can still change it to any value different than a standard maven phase. That is, -Djar.creation=none would also work.

Maven skip specific test [duplicate]

In my maven project I have a number of modules. Is it possible to turn off running unit test for some modules via command line options?
My project takes about 15 mins to run through all unit tests. I would like to speed up the overall build by running just the unit tests in the module I am working on. I do not want to go in and edit each individual pom.xml to achieve this.
I have tried a solution outlined here: Can I run a specific testng test group via maven? However the result is a lot of test failures in modules that I want to skip. I suppose 'group' is not the same concept of module?
To toggle unit tests on and off for an entire project use Maven Surefire Plugin's capability of skipping tests. There is a drawback with using skipTests from the command line. In a multi-module build scenario, this would disable all tests across all modules.
If you need more fine grain control of running a subset of tests for a module, look into using the Maven Surefire Plugin's test inclusion and exclusion capabilities.
To allow for command-line overrides, make use of POM properties when configuring the Surefire Plugin. Take for example the following POM segment:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<excludes>
<exclude>${someModule.test.excludes}</exclude>
</excludes>
<includes>
<include>${someModule.test.includes}</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<someModule.skip.tests>false</someModule.skip.tests>
<skipTests>${someModule.skip.tests}</skipTests>
<someModule.test.includes>**/*Test.java</someModule.test.includes>
<someModule.test.excludes>**/*Test.java.bogus</someModule.test.excludes>
</properties>
With a POM like the above you can execute tests in a variety of ways.
Run all tests (the above configuration includes all **/*Test.java test source files)
mvn test
Skip all tests across all modules
mvn -DskipTests=true test
Skip all tests for a particular module
mvn -DsomeModule.skip.tests=true test
Only run certain tests for a particular module (this example includes all **/*IncludeTest.java test source files)
mvn -DsomeModule.test.includes="**/*IncludeTest.java" test
Exclude certain tests for a particular module (this example excludes all **/*ExcludeTest.java source files)
mvn -DsomeModule.test.excludes="**/*ExcludeTest.java" test
Found a way to exclude on command line:
# Exclude one test class, by using the explanation mark (!)
mvn test -Dtest=!LegacyTest
# Exclude one test method
mvn verify -Dtest=!LegacyTest#testFoo
# Exclude two test methods
mvn verify -Dtest=!LegacyTest#testFoo+testBar
# Exclude a package with a wildcard (*)
mvn test -Dtest=!com.mycompany.app.Legacy*
This is from: https://blog.jdriven.com/2017/10/run-one-or-exclude-one-test-with-maven/
…and if you like to pass the parameter to maven release plugin in Hudson/Jenkins you have to use
-Darguments=-DskipTests
to get it work.
If you want to use Maven profiles:
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
you might want to make it work doing something like this:
Skipping tests in some modules in Maven
I don't know if there is a supported command line option that does the same.
You also might try using environment properties directly, something as per this doc page:
http://maven.apache.org/plugins/maven-surefire-plugin/examples/skipping-test.html
i.e. something like:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<skipTests>${moduleA.skipTests}</skipTests>
</configuration>
</plugin>
then using mvn -DmoduleA.skipTests=false test to test that one module.

surfire plugin maven : env variable for specific tests

I am facing an issue with Maven and the Surefire plugin.
I have two tests: testDatePos.java and testDateNeg.java and for each test an environment variable must be set. It is the same environment variable (DATE_SHIFT) but not the same value (-1 and 1).
Is it possible to configure the section surefire-plugin in the pom.xml of maven to have those tests running?
Here is my pom.xml that exclude the testDatePos.java to have the mvn test running OK (I know this is NOT a solution):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/testDatePos.java</exclude>
<!-- this test needs the env variable DATE_SHIFT=1 but
the test testDateNeg.java needs it at -1 -->
</excludes>
<environmentVariables>
<DATE_SHIFT>-1</DATE_SHIFT>
</environmentVariables>
</configuration>
</plugin>
You can do this by specifying two different executions of surefire in your pom, and forking each execution.
However, this means that these tests will only work when you're running them from maven, or at least you have to change the configuration everywhere you run them from. So, for the tests which require a environment variable, I would add this to the #Before/#After (or #BeforeClass/#AfterClass) of those specific tests.
#Before public void before() {
System.setProperty("DATE_SHIFT", "-1");
}
This way, you don't need to execute the tests in maven for them to work. You'll probably want to store the original value of DATE_SHIFT and restore it at the end of the test.

Resources