Can not append system properties from profile config - maven

I have build configuration for maven failsafe plugin which includes systemPropertyVariables:
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19.1</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<systemPropertyVariables>
<buildDirectory>${project.build.directory}</buildDirectory>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
Also I have a profile which can append few properties to same plugin via pluginManagement:
<profile>
<id>test</id>
<activation>
<property>
<name>test.host</name>
</property>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<TEST_HOST>test.host</TEST_HOST>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
But I can't read properties from this profile. It's working fine if I delete systemPropertyVariables in build plugin configuration section and keep in pluginManagement configuration of profile. It seems that I need to merge these properties when used together, so I tried to add combine.children="append" and combine.self="append" to configuration of plugin, but it didn't help.
UPDATE:
I've found the cause of this issue: I didn't mention that I have parent pom including from this one, and parent pom.xml has these lines:
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<groupId>org.apache.maven.plugins</groupId>
<version>3.0.0-M3</version>
<configuration combine.children="append">
<systemProperties>
<!-- some properties that I don't use -->
</systemProperties>
</configuration>
</plugin>
And these parent pom failsafe configuration is breaking all configs in my pom.xml - if I remove parent pom reference, failsafe properties will be included correctly. I can't just remove parent pom reference and can't modify it (actually I can fork it and edit, but it's not an easy task), is it possible to override these properties, since I don't use them?
Attached minimal reproducible project: https://send.firefox.com/download/88dfb9f933c9567f/#71ij1jbuEuAYgdwIiZQZRg

I managed to do it by adding an extra pom in between the untouchable (or pariah) parent and current child, I call this new middle pom midboy =)
So midboy has only the following difference from pariah;
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<groupId>org.apache.maven.plugins</groupId>
<version>3.0.0-M3</version>
<inherited>false</inherited>
</plugin>
And this pom becomes the the new parent pom of the child, while it uses the original pariah pom as its parent.
child ---[inherits]---> midboy ---[inherits]---> pariah
With inherited:false I essentially cut-off the failsafe plugin being passed into the child and breaking its profile-based configuration addition to its own local failsafe plugin & config. & this works perfectly!
No skipping of the test this time! 😁
Running com.test.so51905256.PropITCase
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.031 s - in com.test.so51905256.PropITCase
p.s. don't forget to add some sort of <activation> for the test profile

Related

Why is my target not getting executed?

I am trying to get ready for deployment and therefore I want to copy the correct configuration files to WEB-INF/classes/ before everything gets packed into the WAR file for either deployment or development.
In the end I want to execute deployment-tasks whenever I call
mvn glcoud:deploy
- which is when I need deployment configuration files - and development-tasks whenever something else gets executed in my project directory.
At the moment I have not decided how exactly I'm going to do it but first of all I try to execute such a "dummy task". Unfortunately it is not working.
This is the profile I configured in the pom.xml:
<profile>
<id>default-profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<configuration>
<target>
<echo message="Hello World!"/>
<copy file="src/main/resource/x.xml" todir="src/main" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
It is supposed to echo "Hello World!" and copy a x.xml file from A to B. I decided to do this in the compile phase which means
mvn clean compile
should actually be enough to get the target executed but .. I wouldn't be here if it worked.
Question: Does somebody know why this is not getting executed?
As mentioned in a comment, I could/should remove pluginManagement from build. However, this would give me an error saying:
Plugin execution not covered by lifecycle configuration: org.apache.maven.plugins:maven-antrun-plugin:1.8:run (execution: compile, phase: compile)
I've added pluginManagement according to an answer of the question "How to solve “Plugin execution not covered by lifecycle configuration” for Spring Data Maven Builds".
The solution below is giving the same “Plugin execution not covered by lifecycle configuration” error
<profile>
<id>default-profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<!-- -->
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
and I am seeing the same for:
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>default-profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<!-- -->
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
<profiles>
In order to make m2e happy and yet being able to meet your requirements, try the following:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<configuration>
<target>
<echo message="Hello World!"/>
<copy file="src/main/resource/x.xml" todir="src/main" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
</plugin>
</plugins>
</build>
Note the additional plugins section which is basically just repeating the artifactId of the plugin.
What's happening here:
Via the pluginManagement section we are telling Maven: whenever the build (via POM configuration or command line execution) needs to execute this plugin, then apply this version by default and this configuration an executions
The m2e not-so-perfect integration between Maven and Eclipse will then be happy about this plugin configuration, however no plugin execution will ever happen unless we effectively declare it
Via the plugins section we are eventually really defining our build, telling Maven to add this plugin to its build plan. No need to specify version, configuration or executions, since we already defined them into the pluginManagement (that is, management of plugins), which will be applied as default configuration/behavior.
For further details concerning the difference between plugins and pluginManagement, check the reference post on SO: Maven: what is pluginManagement.
Further note on the associated phase for such an execution: the prepare-package phase would be a more (semantically correct and maintenability-friendly) choice than compile. Check the official Build Lifecycle phases list for more details. Concerning prepare-package:
perform any operations necessary to prepare a package before the actual packaging.
Update
It appears that not only as described above the prepare-package phase would be a better choice, but it also the right phase to make the m2e plugin perfectly happy in this case.
See POM Reference, Plugin Management:
pluginManagement
However, this only configures plugins that are actually referenced within the plugins element in the children.
That means declaring a plugin in <pluginManagement> is just half of the story. You have to declare it in a <build>/<plugins> section, too, to actually execute its goal.
In your case:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
</plugin>
</plugins>
</build>

Run Maven goal only in parent POM by activation

I am working on integrating a plugin into a multi-module project.
I am using a 3rd party plugin that essentially needs to only by run from the parent project (based on my understanding and usage of it). I tried to accomplish this by using a profile, like so:
<profiles>
<profile>
<id>run-my-guy</id>
<build>
<plugins>
<plugin>
<groupId>com.myproject</groupId>
<artifactId>myproject-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>runThing</goal>
</goals>
<inherited>false</inherited>
</execution>
</executions>
<inherited>false</inherited>
</plugin>
</plugins>
</build>
</profile>
</profiles>
I have several <inherited>false</inherited>, but if I run mvn help:all-profiles I can still see this profile in every single module. If I run my mvn package -P run-my-guy I see this get executed in every single subproject. I want the ability to activate this and I do not want it to be on by default.
If I try to add it the <build> section, like this:
<build>
<plugins>
<plugin>
<groupId>com.myproject</groupId>
<artifactId>myproject-maven-plugin</artifactId>
<inherited>false</inherited>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>runThing</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Here, I also have a few <inherited>false</inherited>, just to try and enforce that the plugin and the execution are not inherited. However, whenI run the package phase, or anything that includes that phase, the runThing goal is included.
How do I run a goal only by activation (like profile or some other feature, or just by explicitly running the goal) and only in the parent?
As shown in an answer for "Run a single Maven plugin execution?", it is now possible (since Maven 3.3.1) to specify an execution Id for a direct goal invocation.
pom.xml
<build>
<plugins>
<plugin>
<groupId>com.myproject</groupId>
<artifactId>myproject-maven-plugin</artifactId>
<inherited>false</inherited>
<executions>
<id>myproject-exec-id</id> <!-- note the execution Id -->
<execution>
<phase>none</phase>
<goals>
<goal>runThing</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
And then invoking the goal from the command line uses the optional #executionId parameter:
mvn myproject:runThing#myproject-exec-id

Is testng.xml file updated automatically

When running testng with mvn, I configured my workspace as required:
My pom.xml file is configured with all the required dependencies and testng.xml contains all the required classes.
Yet, when I add a new test class, the testng.xml isn't updated automatically-
Shouldn't it scan from the root for the corresponding tests? Or will I have to update the testng.xml file manually?
(BTW, my workspace is configured according to the following post: How to call testng.xml file from pom.xml in Maven)
The xml method gives you more granular control of your test sets. It will not be altered automatically, although eclipse will generate xml configs on the fly if you select say a folder and right click run as testng. If you would just like to run all testng annotated test and you have maven configured properly with surefire or failsafe, you don't even need an xml file. Just run "mvn verify" and all test should be run based on annotation. If this doesn't work, please post your surefire/failsafe pom sections.
If you want to configure a particular xml in maven, use something like (surefire or failsafe work the same.):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${failsafe.version}</version>
<configuration>
<argLine>-Xmx1024m</argLine>
</configuration>
<executions>
<execution>
<id>integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
</goals>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
<!-- <groups>functest,perftest</groups> -->
</suiteXmlFiles>
</configuration>
</execution>
</executions>
</plugin>
If you do need more granular control, and would like to use an xml file specified by maven, you launch it via "verify -P MyProfile"
<profiles>
<profile>
<id>MyProfile</id>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>MyProfile.xml</suiteXmlFile>
<!-- <groups>functest,perftest</groups> -->
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>MyOtherProfile</id>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>MyOtherProfile.xml</suiteXmlFile>
<!-- <groups>functest,perftest</groups> -->
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profiles>

Disable a Maven plugin defined in a parent POM

I am using a parent POM that defines a plugin that I do not want to be run in a child POM. How can I disable the plugin in the child pom completely?
Constraint: I cannot change the parent POM itself.
The following works for me when disabling Findbugs in a child POM:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<executions>
<execution>
<id>ID_AS_IN_PARENT</id> <!-- id is necessary sometimes -->
<phase>none</phase>
</execution>
</executions>
</plugin>
Note: the full definition of the Findbugs plugin is in our parent/super POM, so it'll inherit the version and so-on.
In Maven 3, you'll need to use:
<configuration>
<skip>true</skip>
</configuration>
for the plugin.
See if the plugin has a 'skip' configuration parameter. Nearly all do. if it does, just add it to a declaration in the child:
<plugin>
<groupId>group</groupId>
<artifactId>artifact</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
If not, then use:
<plugin>
<groupId>group</groupId>
<artifactId>artifact</artifactId>
<executions>
<execution>
<id>TheNameOfTheRelevantExecution</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
The thread is old, but maybe someone is still interested.
The shortest form I found is further improvement on the example from λlex and bmargulies. The execution tag will look like:
<execution>
<id>TheNameOfTheRelevantExecution</id>
<phase/>
</execution>
2 points I want to highlight:
phase is set to nothing, which looks less hacky than 'none', though still a hack.
id must be the same as execution you want to override. If you don't specify id for execution, Maven will do it implicitly (in a way not expected intuitively by you).
After posting found it is already in stackoverflow:
In a Maven multi-module project, how can I disable a plugin in one child?
I know this thread is really old but the solution from #Ivan Bondarenko helped me in my situation.
I had the following in my pom.xml.
<build>
...
<plugins>
<plugin>
<groupId>com.consol.citrus</groupId>
<artifactId>citrus-remote-maven-plugin</artifactId>
<version>${citrus.version}</version>
<executions>
<execution>
<id>generate-citrus-war</id>
<goals>
<goal>test-war</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
What I wanted, was to disable the execution of generate-citrus-war for a specific profile and this was the solution:
<profile>
<id>it</id>
<build>
<plugins>
<plugin>
<groupId>com.consol.citrus</groupId>
<artifactId>citrus-remote-maven-plugin</artifactId>
<version>${citrus.version}</version>
<executions>
<!-- disable generating the war for this profile -->
<execution>
<id>generate-citrus-war</id>
<phase/>
</execution>
<!-- do something else -->
<execution>
...
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

Automatically activate parent plugin in Maven

Is it possible to have a plugin defined in the parent POM which is deactivated, and when the child inherits this plugin it gets automatically activated?
I guess you want to configure the plugin in your parent pom, but use it only in the inherited projects. Maven has a section for this - configure your plugins in pluginManagement, but bind them to a phase just when you needed it, e.g. omit the phase tag in pluginManagement, but specify it under in you inherited pom.
So 'siddhadev' is exactly correct. You can define the plugin configuration in the parent pom with a given id:
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>child-caller</id>
<!-- 'phase' omitted -->
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo message="called from child!" />
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
And, in the child POM, you can explicitly list the phase where this should be called:
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>child-caller</id>
<phase>compile</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
I've used this for targeting various JREs. Unfortunately, because you can't use the maven-compiler-plugin with different destination directories (which I consider a bug in the plugin), you must use Ant.
This isn't exactly what you're after, but I think it will work well enough for you.
If you declare the plugin in a pluginManagement tag in the parent, the configuration will be inherited by any child projects that declare that plugin.
For example, in the parent declare that the compile plugin uses Java 5 for test compilation.
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>test-compile</id>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
Then in a child, you simple declare the compiler plugin and the configuration from the parent will be inherited:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
You can declare a plugin at the top level pom and tell it to be skipped and then tell it to not be skipped at the child level. It's not quite automatic, but very minimal in the override verbosity.
Parent Pom, disabling the plugin, but declaring all the config:
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-surefire-plugin</artifactid>
<configuration>
<skip>true</skip>
...lots more config...
...lots more config...
...lots more config...
</configuration>
</plugin>
Child Pom, enabling the plugin:
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-surefire-plugin</artifactid>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
I went with the following solution:
Configure the plugin in the parent-pom in the pluginManagement-section. Bind the plugin to an existing phase.
Deactivate the plugin for the parent-pom by binding it to a nonexistent phase: Override the phase in the plugins-section.
Activate the plugin in each child-pom by including the plugin in the plugins section.
Example parent-pom:
<defaultGoal>install</defaultGoal>
<pluginManagement>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-ejb-client</id>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<file>${ejb-client-file}</file>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<packaging>jar</packaging>
<classifier>client</classifier>
</configuration>
</execution>
</executions>
</plugin>
...
</plugins>
</pluginManagement>
<plugins>
<plugin>
<!-- deactivate the plugin for this project, only child-projects do generate ejb-clients -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<inherited>false</inherited>
<executions>
<execution>
<id>install-ejb-client</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
Example child-pom:
<build>
<plugins>
...
<plugin>
<!-- Install the generated client-jar. Property 'ejb-client-file' has to be set! Plugin configuration is in the parent pom -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
</plugin>
...
</plugins>
</build>
As far as I know, there is no generic solution for this. At least for the moment...
One idea (I didn't try it, but it may work) is to define, in the parent pom.xml an execution goal that does not exist, for example:
<executions>
<execution>
<goals>
<goal>noGoal</goal>
</goals>
</execution>
</executions>
and in every child, you redefine a correct goal.
The problem of this solution (if it works, of course ;) ) is that you must redefine the plugin configuration for every child. Otherwise, it will not be executed.

Resources