Jelle den Burger
Jelle den Burger

Reputation: 1468

Run a Maven plugin when the build fails

I am using a plugin to send a Slack message through Maven. I am wondering if it's possible to use a plugin when the build failed so I get automatically notified about the failed build?

Upvotes: 5

Views: 1543

Answers (1)

Tunaki
Tunaki

Reputation: 137319

You could do that within Maven itself, through the EventSpy mechanism, built-in from Maven 3.0.2. At each step of the build, several events are raised by Maven itself, or by custom code, and it is possible to listen to those events to perform some actions. The execution event raised by Maven are represented by the class ExecutionEvent. Each event has a type, that describes what kind of event it represents: project failure, Mojo failure, project skipped, etc. In this case, the project failure event is what you're looking for.

A custom spy on events is just a Java class that implements the EventSpy interface. Preferably, it should inherit from the AbstractEventSpy helper class. As an example, create a new project (let's call it my-spy), and add the following Java class under a package:

import org.apache.maven.eventspy.AbstractEventSpy;
import org.apache.maven.eventspy.EventSpy;
import org.apache.maven.execution.ExecutionEvent;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;

@Component(role = EventSpy.class)
public class BuildFailureEventSpy extends AbstractEventSpy {

    @Requirement
    private Logger logger;

    @Override
    public void onEvent(Object event) throws Exception {
        if (event instanceof ExecutionEvent) {
            ExecutionEvent executionEvent = (ExecutionEvent) event;
            if (executionEvent.getType() == ExecutionEvent.Type.ProjectFailed) {
                logger.info("My spy detected a build failure, do the necessary here!");
            }
        }
    }

}

This code simply registers the spy through the Plexus' @Component annotation, and logs a message when a project failed to build. To compile that class, you just need to add to the my-spy project a dependency on Maven Core and an execution of the plexus-component-metadata plugin to create the right Plexus metadata for the component.

<dependencies>
  <dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-core</artifactId>
    <version>3.0.2</version>
  </dependency>
</dependencies>
<build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.plexus</groupId>
      <artifactId>plexus-component-metadata</artifactId>
      <version>1.6</version>
      <executions>
        <execution>
          <goals>
            <goal>generate-metadata</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Once this project is compiled and installed into your local repository (through mvn clean install), you can add it to the build of another project through the core extensions mechanism.

Before Maven 3.3.1, you had to drop the my-spy JAR into your ${MAVEN_HOME}/lib/ext folder, so that Maven could find it. As of 3.3.1, you don't need to fiddle with your Maven installation, and can create a file .mvn/extensions.xml in your project base directory (${maven.multiModuleProjectDirectory}/.mvn/extensions.xml). Its content would be

<?xml version="1.0" encoding="UTF-8"?>
<extensions>
  <extension>
    <groupId>my.spy</groupId>
    <artifactId>my-spy</artifactId>
    <version>0.0.1</version>
  </extension>
</extensions>

which just declares an extension pointing to the Maven coordinates of the spy project. Maven (≥ 3.3.1) will by default look for that file, and, as such, your spy will be correctly registered and invoked throughout the build.


The only remaining thing to do, is to code what the spy should do. In your case, it should invoke a Maven plugin, so you take a look at the Mojo Executor library, which makes that very easy to do.

Upvotes: 5

Related Questions