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

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Using Python Libraries in Java
  • DGS GraphQL and Spring Boot
  • How to Build a New API Quickly Using Spring Boot and Maven
  • Configurable Feign Client Retry With Reusable Library and DRY

Trending

  • AI, ML, and Data Science: Shaping the Future of Automation
  • *You* Can Shape Trend Reports: Join DZone's Software Supply Chain Security Research
  • Build Your First AI Model in Python: A Beginner's Guide (1 of 3)
  • How to Build Local LLM RAG Apps With Ollama, DeepSeek-R1, and SingleStore
  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
19.9K 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, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Using Python Libraries in Java
  • DGS GraphQL and Spring Boot
  • How to Build a New API Quickly Using Spring Boot and Maven
  • Configurable Feign Client Retry With Reusable Library and DRY

Partner Resources

×

Comments

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

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

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 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: