Use of Execution Tag in Maven - java

What is the purpose of Execution tag in Maven?
I run testng.xml using POM file, With and Without using execution tag ,i get the same output using mvn clean.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<executions>
<execution>
<id>testngtest</id>
<phase>test</phase>
</execution>
</executions>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>${testngxml.location}/testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
Then why we are using Execution tag?

It is because for "maven-surefire-plugin", test is the default phase.
Hence nothing got changed for it.
Change the phase to compile or other phase.

The <execution> block is required to bind plugin execution to one of Maven's lifecycles. For surefire this is not necessary, since it is bound to the test phase by default.
Note that the <execution> block can also contain a <configuration> block, so you can have multiple executions with different configurations. You can read more about it in the Maven documentation on configuring plugins.

The execution tag is most commonly used for mojos that are intended to participate in some phases of the build lifecycle. i.e you hjave configured maven-surefire-plugin to run in the testing phase of the build life cycle which is where it runs by default anyway so this has no effect. Since surefire is bound to the test phase by default, I'm not sure changing the phase in executions would have any effect. You would need to try a different plugin and try changing the execution setting on that plugin. Maybe try the one in the documentation 'maven-myquery-plugin'
See the dopcumentation on the executions tag here

Related

Cannot execute Groovy Maven Plugin as a goal

I am using Apache Maven 3.3.9 with the Groovy Maven plugin. Here is the relevant section of the pom.xml (the inlined Groovy script is just fictional):
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<id>myGroovyPlugin</id>
<phase>prepare-package</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
log.info('Test message: {}', 'Hello, World!')
</source>
</configuration>
</execution>
</executions>
</plugin>
If I am calling mvn install the inline Groovy script gets called by the plugin as part of the prepare-package phase and works just fine. But if I try to call the plugins' goal directly via mvn groovy:execute I get the following error message:
[ERROR] Failed to execute goal org.codehaus.gmaven:groovy-maven-plugin:2.0:execute (default-cli) on project exercise02: The parameters 'source' for goal org.codehaus.gmaven:groovy-maven-plugin:2.0:execute are missing or invalid -> [Help 1]
The error you are getting is already pointing at the issue: the plugin couldn't not find the source configuration option because indeed it is only configured within the myGroovyPlugin execution, that is, only in the execution scope and not as a global configuration.
This is the main difference between configuration element outside the executions (global configuration for all executions of the plugin (even from command line) and within an execution (configuration only applied to that particular goal execution).
To fix the issue you should move the configuration element outside the executions section in this case, since the plugin is not a plugin invoked during default bindings by Maven, it would be enough and not have impact on your build: it will be still used during the myGroovyPlugin execution AND from explicit executions from command line.
From Maven POM reference, the configuration within an execution:
confines the configuration to this specific list of goals, rather than all goals under the plugin.
To make it clear, you should change it to the following:
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<id>myGroovyPlugin</id>
<phase>prepare-package</phase>
<goals>
<goal>execute</goal>
</goals>
</execution>
</executions>
<configuration>
<source>log.info('Test message: {}', 'Hello, World!')</source>
</configuration>
</plugin>
As such the configuration will become a global configuration and applied to both command line executions and declared executions.
Since you are using Maven 3.3.9, you could also make use of a slightly more verbose pattern to invoke directly a specific configuration of an execution:
mvn groovy:execute#myGroovyPlugin
This pattern is useful in cases where you really don't want a global configuration because you don't want to impact other (often default) executions of a certain plugin and you really want to use a specific isolated configuration both in an execution and from command line.

How to validate XML after Maven filtering?

Assume that I have a simple XML file:
<?xml version="1.0" encoding="UTF-8"?>
<root property="${my.custom.maven.property}"/>
Because my.custom.maven.property is obtained by Maven plugin, I can't modify its value and it is non-escaped UTF-8 String, so it may (and it does) contain a special characters like ". This would lead to error after packaging or compilation phases (mostly at deployed server...). I want to prevent that situation by XML validation.
The point here is I am using xml-maven-plugin:validate. That won't help, because I can't specify that this validation should be done after filtering (well, filtering here means injecting those Maven property value). Plugin config looks really simple:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>validate</goal>
</goals>
</execution>
</executions>
<configuration>
<validationSets>
<validationSet>
<dir>xml_root</dir>
<includes>
<include>**/*.xml</include>
</includes>
</validationSet>
</validationSets>
</configuration>
</plugin>
The Maven properties injection is handled by the Resources Plugin which has a bind by default to the process-resources phases, while the XML Maven Plugin validate goal has a default binding to the test phase, probably too late during your build.
You can move the XML validation earlier in the Maven lifecycle and apply it right after the properties injection binding it to the process-resources phase as well as following:
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>validate</goal>
</goals>
</execution>
</executions>
Note the additional phase element.
As such, Maven would inject and then validate the XML and your build will fail (if required) much earlier.
For a full list of phases and their order, check official Maven documentation here.
Beware: in case you would use it, some Eclipse (m2e) versions may not like a different phase binding, you can ignore this error as long as the command line build works fine (always trust the command line build).

Serial execution of plugins in Maven using <phase>

I have the following structure in pom.xml:
<profile>
<id> x </id>
<build>
<finalName> y </finalName>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<!-- DELETE SOME FOLDERS AND SOME FILES -->
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<!-- MOVE A FILE -->
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version> 1.6 </version>
<executions>
<execution>
<phase> <!-- WHAT COMES HERE ? --> </phase>
<configuration>
<!-- I EXECUTE CMD FILE HERE -->
</configuration>
<goals>
<goal> run </goal>
</goals>
<execution>
<executions>
</plugin>
</plugins>
</build>
</profile>
I want to achieve a serial execution for plugins:
Delete some folders and some files (1st plugin)
Move a file (2nd plugin)
Run cmd file (3rd plugin)
What should I use for <phase> to have the order above (sequential execution)? Is it relevant ? Is it ok to use pre-integration-test for example ?
P.S.: Here are the phases: http://maven.apache.org/ref/3.2.2/maven-core/lifecycles.html
Maven doesn't support adding steps to the life cycle (without writing a new plugin).
If you have complex build steps and you absolutely need a certain order and this order violates the standard life cycle, then Maven might not be the right tool for you. Consider Gradle instead.
If you have to use Maven, then stop using plugins for this. Instead, replicate all the build steps using the antrun plugin so everything is done with a single Ant script. Afterwards, find a place in the life cycle where you want all the steps to be executed at once.
generate-sources is a good place if you need something to be done before anything is compiled. If you want to run code after compilation and tests, use prepare-package.
See here for the complete life cycle: http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference
If you like to add the execution of different plugins to the same life cycle phase the execution order is defined by the order of the definition in the pom file.
So if you choose to bind all the above three plugins to the package phase than they will be executed in the given order.
You can of course use the antrun plugin which will work also and will implicit execute the steps in the defined order without thinking about the default behaviour of Maven.
You can also use the exec-maven-plugin to execute a script in a particular life cycle phase but which might be not a good solution cause the script is OS dependent. Or you can use the groovy plugin to execute some steps in groovy code.

Mechanics of Goal execution in Maven

I have the wsimport plugin in my project.
I would like to execute the wsimport. According to the website, the string to execute is "mvn jaxws:wsimport".
Firstly, is this string deductable from the XML ?
The artifact ID is :
<artifactId>jaxws-maven-plugin</artifactId>
and goal :
<goal>wsimport</goal>
so is the artifact-part just the substring of the artifactid leading up to "-maven-plugin" ?
..And when I execute my plugin goal "mvn jaxws:wsimport" does this completely ignore which phase I am in? Ie. is this running outside of the phase? And if no, is there a way to run this standalone?
ie. is there a way I can set the phase to none? (eg [phase]none[/phase]).
Pom code :
<build>
<plugins>
<plugin>
<groupId>org.jvnet.jax-ws-commons</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>wsimport-from-jdk</id>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<executable>${tool.wsimport}</executable>
<wsdlUrls>
<wsdlUrl>http://WorkPC:8080/server-web/AirlineWS?wsdl</wsdlUrl>
</wsdlUrls>
<packageName>com.bluewalrus</packageName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
When you issue a command like mvn [plugin]:[goal], it launches Maven out of any lifecycle, so if you do not intend to perform that goal inside a lifecycle, but only via such commands, you shouldn't have any <execution> defined, just place <configuration> right after <version>.
About how Maven can shorten the plugin call (i.e. mvn dependency:tree instead of mvn org.apache.maven.plugins:maven-dependency-plugin:2.1:tree), it is based on several conventions:
When no version defined, it tries to take the latest from available repositories
When the groupId is omitted, it looks among the predefined or user-defined pluginGroups to find a suitable one. See here for more information (Configuring Maven to Search for Plugins)
On the same page, you can see how plugins prefixes are used to shorten the plugin prefix, by using a prefix instead of the artifactId of the plugin. Thirdparty plugins should use [prefix]-maven-plugin construction, and it looks OK here.
And to disable the default execution of a plugin (although it might not be useful in this case), you can use this answer

How to make my compilation plugin override the maven one?

I'd like my plugin to be executed in the compilation phase. But when I do it like this it fails due to "duplicate class" errors. When I run this in a different phase everything works fine. How to deal with it so that I could just swap the default maven compilation behavior with the one I've created?
Thanks!
I believe you have two options, neither of them are particularly nice.
Set the phase of the compiler plugin to none, which will stop it from being executed. i.e.
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
It should be noted the reason this option isn't particularly nice is that setting <phase>none</phase> is an undocumented feature and so could be removed in a future version of maven.
Set the packaging of your project to something other than jar. This will then remove the default execution of the compiler plugin. But it will also remove the execution of all other plugins (i.e. resources, surefire, jar, etc) so you would have to add them back in manually.

Categories

Resources