Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven profile - How to run plugin once for parent and more for modules?

I'm a little puzzled by my Jenkins output.

Job on Jenkins: (shortened pom.xml at the bottom)

mvn deploy -Pprofile1

All my plugins will run 4 times:

  • parent/pom.xml
  • parent/module1/pom.xml
  • parent/module2/pom.xml
  • parent/module3/pom.xml

I need:

  • first-maven-plugin: only run once in the parent pom.xml
  • second-maven-plugin: run for every pom.xml

Why:

  • first-maven-plugin: will run in phase:initialize --> rather long cleanup operation. Don't want this 4 times
  • second-maven-plugin: will run in phase:package --> necesaary for all pom's.

Parent pom.xml

<project ...>

    <groupId>com.test.parent</groupId>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>parent</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>parent</name>

    <modules>
        <module>module1</module>
        <module>module2</module>
        <module>module3</module>
    </modules>

    <profiles>
        <profile>
            <id>profile1</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>com.test.plugin</groupId>
                        <artifactId>first-maven-plugin</artifactId>
                        <version>1.0.0-SNAPSHOT</version>
                        <execution>
                            <id>execution1</id>
                            <phase>initialize</phase>
                            <goals>
                                <goal>doit</goal>
                            </goals>
                        </execution>
                    </plugin>
                    <plugin>
                        <groupId>com.test.plugin2</groupId>
                        <artifactId>second-maven-plugin</artifactId>
                        <version>1.0.0-SNAPSHOT</version>
                        <execution>
                            <id>another</id>
                            <phase>package</phase>
                            <goals>
                                <goal>goforit</goal>
                            </goals>
                        </execution>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

</project>
like image 734
Dimitri Dewaele Avatar asked Mar 25 '16 08:03

Dimitri Dewaele


People also ask

How to configure Maven profile with Maven project?

Steps to Configure Maven Profile with Maven Project 1 Project should be a Maven Project. 2 Maven Jar files should be downloaded and path must be set for the same in Environment Variables and ensure that you... More ...

What is the use of plugins in Maven?

Plugin configurations allow us to reuse a common build logic across projects. If the parent has a plugin, the child will automatically have it without additional configuration. This is like an inheritance. To achieve this, Maven merges the XML files at the element level.

How to create Maven projects with parent child relationship?

Let’s learn to create maven projects with parent child relationship. Project creation wizard. Select Project Archtype. Fill details and create project. Now change packaging from jar to pom in pom.xml. Additionally, add project properties and dependencies. Create a new maven project just like you did for parent project.

How to configure Maven plugin in Mojo?

Maven plugins (build and reporting) are configured by specifying a <configuration> element where the child elements of the <configuration> element are mapped to fields, or setters, inside your Mojo. (Remember that a plug-in consists of one or more Mojos where a Mojo maps to a goal.) Say, for example, you have a Mojo that performs a query ...


2 Answers

You can use <inherited>false</inherited> in the first plugin configuration. So it will only run in parent pom execution.

<build>
    <plugins>
        <plugin>
            <groupId>com.test.plugin</groupId>
            <artifactId>first-maven-plugin</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <inherited>false</inherited>
            <execution>
                <id>execution1</id>
                <phase>initialize</phase>
                <goals>
                    <goal>doit</goal>
                </goals>
            </execution>
        </plugin>
        <plugin>
            <groupId>com.test.plugin2</groupId>
            <artifactId>second-maven-plugin</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <execution>
                <id>another</id>
                <phase>package</phase>
                <goals>
                    <goal>goforit</goal>
                </goals>
            </execution>
        </plugin>
    </plugins>
</build>

See https://stackoverflow.com/a/1671175

like image 159
julianwki Avatar answered Sep 30 '22 00:09

julianwki


First if you define a plugin in the parent which is inherited to all children than it is exactly behaving as you wished which means it is executing on every pom (or in other word on every module doesn't matter if it is a child or not).

The problem of your plugins is that they handle the use cases not very good. Cause you are saying the first one first-maven-plugin should run only on root level (Apart from that i don't understand what you mean by cleanup operation...removing target folder?)

And the second plugin second-maven-plugin should run for all pom's? Which is not very accurate cause do you mean by pom all child modules which having packaging pom? But i assume you mean all children which have packaging jar?

Apart from the above i'm not sure if the usage of your profile is only based on the lack of handling the use cases correct.

The result of the above i would conclude you need to change the implementation of your plugins.

If you like having a plugin run only on the root level of such a multi module structure this can handle in a very simple way in your plugin like this:

public void execute()
    throws MojoExecutionException, MojoFailureException
{

    if (mavenProject.isExecutionRoot()) {

    } else {

    }

 ..

By using the above your plugin can decide if it is running on root level or not.

So your first-maven-plugin can use the following:

public void execute()
    throws MojoExecutionException, MojoFailureException
{

    if (!mavenProject.isExecutionRoot()) {
       getLog().info("Not running at root level");
       return;  
    } 
    // here the time consuming operations        
 ..

And your second-maven-plugin to do the oposite:

public void execute()
    throws MojoExecutionException, MojoFailureException
{

    if (mavenProject.isExecutionRoot()) {
       getLog().info("Not running at root level");
       return;  
    } 
    // here the operation on the childs.
 ..

The behaviour can be improved via the following:

public void execute()
    throws MojoExecutionException, MojoFailureException
{

    if (!mavenProject.isExecutionRoot()) {
       getLog().debug("Not running at root level");
       return;  
    } 

    if ("pom".equals(project.getPackaging())) {
        getLog().debug("Ignoring pom packaging.");
        return;
    }
    // ..now the operations you would like to do...

So if you have several levels of module hierarchy you can ignore the pom packaging parts or other parts etc.

And last but not least. What do your plugins archive?

like image 24
khmarbaise Avatar answered Sep 30 '22 00:09

khmarbaise