Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to override default binding to phase of a Maven plugin

Tags:

maven

I want to define different executions for plugins in the pluginManagement of my parent pom and then bind specific executions to phases in the child poms. I see inconsistent behavior depending on the plugin used and the location of the pluginManagement section.

In this first example the pluginManagement is located in the parent pom, defining 2 executions for compiler plugin and 2 executions for antrun plugin.

<?xml version="1.0" encoding="UTF-8"?>
<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">
<name>master-pom</name>
<modelVersion>4.0.0</modelVersion>
<groupId>plugin.test</groupId>
<artifactId>master-pom</artifactId>
<packaging>pom</packaging>
<version>1.0.0-SNAPSHOT</version>
<build>
    <pluginManagement>
        <plugins>               
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <executions>
                    <execution>
                        <id>execution-1</id>
                        <phase>none</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <source>1.6</source>
                            <target>1.6</target>
                            <includes>
                                <include>**/*</include>
                            </includes>
                        </configuration>
                    </execution>
                    <execution>
                        <id>execution-2</id>
                        <phase>none</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <source>1.5</source>
                            <target>1.5</target>
                            <includes>
                                <include>**/*</include>
                            </includes>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.7</version>
                <executions>
                    <execution>
                        <id>execution-1</id>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>
                                <echo message="execution 1"/>
                            </target>
                        </configuration>
                    </execution>
                    <execution>
                        <id>execution-2</id>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>
                                <echo message="execution 1"/>
                            </target>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </pluginManagement>
</build>

And the child pom:

<?xml version="1.0" encoding="UTF-8"?>
<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">
<name>build</name>
<modelVersion>4.0.0</modelVersion>
<groupId>plugin.test</groupId>
<artifactId>build</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
    <groupId>plugin.test</groupId>
    <artifactId>master-pom</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <relativePath>./master-pom.xml</relativePath>
</parent>
<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <executions>
                <execution>
                    <id>execution-1</id>
                    <phase>generate-sources</phase>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <id>execution-1</id>
                    <phase>generate-sources</phase>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Running 'mvn clean install' on the child pom will run both executions of the compiler plugin and only the 1st execution of the antrun plugin, although only the 1st execution of each was bound to a phase.

Now moving the pluginManagement to the child pom:

<?xml version="1.0" encoding="UTF-8"?>
<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">
<name>build</name>
<modelVersion>4.0.0</modelVersion>
<groupId>plugin.test</groupId>
<artifactId>build</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<build>
    <pluginManagement>
        <plugins>               
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <executions>
                    <execution>
                        <id>execution-1</id>
                        <phase>none</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <source>1.6</source>
                            <target>1.6</target>
                            <includes>
                                <include>**/*</include>
                            </includes>
                        </configuration>
                    </execution>
                    <execution>
                        <id>execution-2</id>
                        <phase>none</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <source>1.5</source>
                            <target>1.5</target>
                            <includes>
                                <include>**/*</include>
                            </includes>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.7</version>
                <executions>
                    <execution>
                        <id>execution-1</id>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>
                                <echo message="execution 1"/>
                            </target>
                        </configuration>
                    </execution>
                    <execution>
                        <id>execution-2</id>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>
                                <echo message="execution 2"/>
                            </target>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </pluginManagement>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <executions>
                <execution>
                    <id>execution-1</id>
                    <phase>generate-sources</phase>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <id>execution-1</id>
                    <phase>generate-sources</phase>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

This pom gives the desired behavior which is running only the 1st execution for each plugin. The compiler plugin (and most others) works correctly only in the case where the pluginManagement is located in the same pom and every execution is bound to phase=none (probably because it binds executions to a default phase). The antrun plugin works correctly in any case.

How can I achieve this while having the pluginManagement section in the parent pom and without having to specifically bind unwanted executions to phase=none in the child poms? Is this a bug in Maven or is this behavior somehow justified? I have tried this on Maven 3.0.4 and Maven 2.2.1 with the same results.

like image 354
Rigas Grigoropoulos Avatar asked Nov 06 '12 11:11

Rigas Grigoropoulos


1 Answers

The example provided works correctly. I had not redeployed the parent after including the fix.

Most plugins will bind executions to a default phase. So when one execution of a plugin is triggered, all unbound executions will be bound to the default phase and will also run.

To avoid this behavior, all executions of the plugin in the pluginManagement section of the parent pom should be bound to phase=none (as shown in the provided example). This way no execution will run unless the phase is explicitly overridden in the child poms.

like image 118
Rigas Grigoropoulos Avatar answered Sep 22 '22 10:09

Rigas Grigoropoulos