DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • OpenAPI From Code With Spring and Java: A Recipe for Your CI
  • Tracking Dependencies Beyond the Build Stage
  • Automating Maven Dependency Upgrades Using AI
  • Web App Load Testing Using Maven Plugins for Apache JMeter, and Analyzing the Results

Trending

  • Architecting Sub-Microsecond HFT Systems With C++ and Zero-Copy IPC
  • DuckDB for Python Developers
  • Context Is the New Schema
  • Building a Skill-Based Agentic Reviewer with Claude Code: A Practical Guide Using Skills.MD, MCP Servers, Tools, and Tasks
  1. DZone
  2. Coding
  3. Java
  4. Beginner's Guide to Creating a Maven Plugin

Beginner's Guide to Creating a Maven Plugin

In this article, we'll learn how to build a Maven plugin and test it. Read on to get started!

By 
Swathi Prasad user avatar
Swathi Prasad
·
May. 29, 19 · Tutorial
Likes (7)
Comment
Save
Tweet
Share
20.4K Views

Join the DZone community and get the full member experience.

Join For Free
Maven Project Tutorial

Maven plugins are software components that allow for the reuse of common build logic across multiple projects or modules. In this article, I would like to demonstrate how to build a Maven plugin and test it.

Creating a Maven Plugin Project

This article assumes that you have already installed Maven. In this article, I am going to create a small plugin which creates a zip file for multiple files listed in a directory. Create a Maven project using the command maven-archetype-mojo .

Basic Maven Project

Provide a suitable GroupId and ArtifactId. Make sure your GroupId and ArtifactId follow the guidelines provided here. This is important if you want to publish your plugin to a Maven Central repository.

Maven Repository

Continue by clicking Next. Once you click Finish, you will see that a POM file and a Mojo class have been created. Mojo is a goal in Maven. We can define metadata such as the goal's name, its lifecycle phase, and so on within a  Mojo class.

In pom.xml, make sure to add the following plugin to be able to use Maven plugin annotations.

<dependency>
      <groupId>org.apache.maven.plugin-tools</groupId>
      <artifactId>maven-plugin-annotations</artifactId>
      <version>3.6.0</version>
      <scope>provided</scope>
 </dependency>

Add the Maven project plugin. I will explain the purpose of this plugin in a bit.

<dependency>
   <groupId>org.apache.maven</groupId>
   <artifactId>maven-project</artifactId>
  <version>2.2.1</version>
</dependency>

This Mojo class always extends an abstract class, AbstractMojo, which provides the infrastructure to implement a plugin.

When we create a Maven project in an IDE, the default name for the Mojo class will be something like MyMojo. I have renamed it to  FileZipMojo since our plugin will be about creating a zip file.

@Mojo (name = "zip", defaultPhase = LifecyclePhase.GENERATE_RESOURCES)
public class FileZipMojo extends AbstractMojo {

The goal name for this plugin is "zip" and lifecycle phase is GENERATE_RESOURCES because it generates a zip file. I will show you how to use it in a bit later in this article.

In the next step, I will define three parameters required for our plugin execution.

@Parameter (required = true)
    private File input;

    @Parameter
    private File zipName;

    /**
     * @parameter default-value="${project}"
     * @required
     * @readonly
     */
    @Parameter(defaultValue = "${project}", required = true, readonly = true)
    MavenProject project;

The parameter input is mandatory which accepts file directory path. The plugin scans this directory path and creates a zip file. The parameter zipName is zip file name which is optional. If not provided, we will use the default name.

If we want to use project information where this plugin is included, we can define MavenProject to get access to the project information such as project name, version and so on. Therefore, we included maven-project plugin.

Let us complete our plugin execution. Here is the complete code.

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.techshard;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Main class for creating file zip.
 *
 * @author Swathi Prasad
 *
 */
@Mojo (name = "zip", defaultPhase = LifecyclePhase.GENERATE_RESOURCES)
public class FileZipMojo extends AbstractMojo {

    @Parameter (required = true)
    private File input;

    @Parameter
    private File zipName;

    /**
     * @parameter default-value="${project}"
     * @required
     * @readonly
     */
    @Parameter(defaultValue = "${project}", required = true, readonly = true)
    MavenProject project;

    private static final String FILE_EXTENSION= ".zip";

    public void execute() throws MojoExecutionException {
        getLog().info("Zipping files in \"" + input.getPath() + "\".");

        final String outputFileName = zipName != null ? zipName + FILE_EXTENSION : project.getName() + "-" + project.getVersion() + FILE_EXTENSION;

        try {
            final File dir = new File(input.getPath());
            final File[] files = dir.listFiles();

            if (files != null) {
                final FileOutputStream fos = new FileOutputStream(outputFileName);
                final ZipOutputStream zipOut = new ZipOutputStream(fos);
                for (final File file : files) {
                    final String fileName = file.getName();

                    getLog().info("Zipping File  " + fileName);

                    final FileInputStream fis = new FileInputStream(file);
                    final ZipEntry zipEntry = new ZipEntry(file.getName());

                    if (file.isDirectory()){
                        if (fileName.endsWith("/")){
                            zipOut.putNextEntry(new ZipEntry(fileName));
                        } else {
                            zipOut.putNextEntry(new ZipEntry(fileName + "/"));
                        }
                    } else {
                        zipOut.putNextEntry(zipEntry);
                    }

                    final byte[] bytes = new byte[2048];
                    int length;
                    while((length = fis.read(bytes)) >= 0) {
                        zipOut.write(bytes, 0, length);
                    }
                    fis.close();
                }
                zipOut.close();
                fos.close();
            }
        } catch(final FileNotFoundException e) {
            throw new MojoExecutionException("No file found", e);
        } catch(final IOException e) {
            throw new MojoExecutionException("Exception reading files", e);
        }
    }
}

Now that we have completed the execution code. Let us install the plugin in our local repository.

In pom.xml, I have included some additional plugins to generate sources and documentation. In addition to these plugins, I have added information about GitHub repository URL, license, and so on. Here is the complete POM.

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.techshard.filezip</groupId>
  <artifactId>filezip-maven-plugin</artifactId>
  <packaging>maven-plugin</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>filezip-maven-plugin Maven Mojo</name>
  <url>http://maven.apache.org</url>

  <scm>
    <connection>scm:git:https://github.com/swathisprasad/filezip-maven-plugin.git</connection>
    <developerConnection>scm:git:https://github.com/swathisprasad/filezip-maven-plugin.git</developerConnection>
    <url>https://github.com/swathisprasad/filezip-maven-plugin</url>
    <tag>HEAD</tag>
  </scm>

  <licenses>
    <license>
      <name>Apache 2.0 License</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
      <distribution>repo</distribution>
    </license>
  </licenses>

  <issueManagement>
    <system>Github</system>
    <url>https://github.com/swathisprasad/filezip-maven-plugin/issues</url>
  </issueManagement>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-plugin-api</artifactId>
      <version>2.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven.plugin-tools</groupId>
      <artifactId>maven-plugin-annotations</artifactId>
      <version>3.6.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-project</artifactId>
      <version>2.2.1</version>
    </dependency>
  </dependencies>

  <build>
    <resources>
      <resource>
        <directory>${project.basedir}</directory>
        <includes>
          <include>LICENSE*</include>
        </includes>
      </resource>
    </resources>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <version>3.0.1</version>
        <executions>
          <execution>
            <id>attach-sources</id>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-javadoc-plugin</artifactId>
        <version>2.10.4</version>
        <configuration>
          <encoding>UTF-8</encoding>
        </configuration>
        <executions>
          <execution>
            <id>attach-javadoc</id>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

We are now ready to install the plugin in our local Maven repository. Run mvn clean install in your terminal.

Testing the Maven Plugin

I will create a simple maven project to test our filezip-maven-plugin.

In pom.xml, let us add the following section.

<build>
        <plugins>
            <plugin>
                <groupId>com.techshard</groupId>
                <artifactId>filezip-maven-plugin</artifactId>
                <version>1.0-SNAPSHOT</version>
                <executions>
                    <execution>
                        <configuration>

                            <input>${project.basedir}/src/main/resources</input>
                            <zipName>test</zipName>

                        </configuration>
                        <goals>
                            <goal>zip</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

We have specified the goal as zip in "goals" section and provided required and optional parameters in the "executions" section. This is just an example, we can include the plugin wherever required.

Create some text files in project resources folder which would be used for creating zip file.

Run mvn clean install. Once the build is complete, navigate to the project root folder and we should see test.zip file.

Conclusion

I hope this article serves as a starting reference point for anyone who wants to create a Maven plugin. The plugin described in this article is just an example. Let me know if you have any suggestions or comments.

The example explained in this article can be found on GitHub repository.

Apache Maven

Published at DZone with permission of Swathi Prasad. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • OpenAPI From Code With Spring and Java: A Recipe for Your CI
  • Tracking Dependencies Beyond the Build Stage
  • Automating Maven Dependency Upgrades Using AI
  • Web App Load Testing Using Maven Plugins for Apache JMeter, and Analyzing the Results

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook