Saturday, 24 October 2020

Maven plugins explained

In this post, I am going to explain about maven plugins.

 

What is Maven Plugin?

Plugin is a core concept of Maven, where all the work in maven is done by plugins. Plugin has one or more goals to be executed.

 

You can declare a plugin in maven pom.xml and customize the configuration as per your needs.

 

For example, 'spring-boot-maven-plugin' is used to genearte a jar file for a spring project.

 

Types of plugins

There are two types of plugins

a.   Build plugins: These plugins get executed during build process. These plugins are configured using <build> element.

Example

<build>

    <plugins>

        <plugin>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-maven-plugin</artifactId>

            <executions>

                <execution>

                    <goals>

                        <goal>repackage</goal>

                    </goals>

                </execution>

            </executions>

        </plugin>

    </plugins>

</build>

 

b.   Reporting plugins: These plugins get executed during site creation and configured using <reporting> element.

 

Reporting plugins are both internationalized and localized (https://maven.apache.org/plugins/localization.html).

Example

  <reporting>

    <plugins>

      <plugin>

        <groupId>org.apache.maven.plugins</groupId>

        <artifactId>maven-surefire-report-plugin</artifactId>

        <version>3.0.0-M5</version>

      </plugin>

    </plugins>

  </reporting>

 

Dependency plugin

The dependency plugin provides the capability to manipulate artifacts. It can copy and/or unpack artifacts from local or remote repositories to a specified location.

 

Dependency plugin has several goals to be executed.

 

Example

dependency:analyze analyzes the dependencies of this project and determines which are: used and declared; used and undeclared; unused and declared.

dependency:analyze-dep-mgt analyzes your projects dependencies and lists mismatches between resolved dependencies and those listed in your dependencyManagement section.

 

Following are the different uses of dependency plugin.

a.   Copying Specific Artifacts

b.   Copying Project Dependencies

c.    Unpacking Specific Artifacts

d.   Unpacking the Project Dependencies

e.   Rewriting target path and file name

f.     Using Project Dependencies' Sources

g.   Failing the Build on Dependency Analysis Warnings

h.   Exclude Dependencies from Dependency Analysis

i.     Filtering the Dependency Tree

j.     Resolving Conflicts Using the Dependency Tree

k.    Purging the local repository

 

For example, lets create pom.xml with below content and experiment with different goals of dependency plugin.

 

pom.xml

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sample.app</groupId>
    <artifactId>hello-world</artifactId>
    <version>1</version>

    <dependencies>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>

    </dependencies>
</project>

 

dependency:tree goal: displays the dependency tree for this project.

Go to the location where pom.xml is located and execute the command ‘mvn dependency:tree’


As you see above image, dependency:tree goals tells us that application hello-world is dependent on gson jar.

 

Let’s add junit library to pom.xml and re-execute dependency:tree goal.

 

Updated pom.xml

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sample.app</groupId>
    <artifactId>hello-world</artifactId>
    <version>1</version>

    <dependencies>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>


        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

    </dependencies>
</project>


Re-execute the command ‘mvn dependency:tree’.

$mvn dependency:tree
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------< com.sample.app:hello-world >---------------------
[INFO] Building hello-world 1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ hello-world ---
[INFO] com.sample.app:hello-world:jar:1
[INFO] +- com.google.code.gson:gson:jar:2.8.5:compile
[INFO] \- junit:junit:jar:4.12:test
[INFO]    \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.860 s
[INFO] Finished at: 2020-10-24T18:23:55+05:30
[INFO] ------------------------------------------------------------------------


As you see the ouput, dependency:tree goals is giving transitive dependencies also (Example, junit library is dependent on hamcrest library).

 

How to configure a plugin?

You can customize the plugin in pom.xml. For example, lets add 'maven-dependency-plugin' to pom.xml and write dependency:tree goal output to a file.

 

Example

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.1.2</version>
                <configuration>
                    <outputFile>project_dependency_tree.txt</outputFile>
                </configuration>
            </plugin>
        </plugins>
    </build>


Updated pom.xml file

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sample.app</groupId>
    <artifactId>hello-world</artifactId>
    <version>1</version>

    <dependencies>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>


        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.1.2</version>
                <configuration>
                    <outputFile>project_dependency_tree.txt</outputFile>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>


Execute the command ‘mvn dependency:tree’ again, you will see ‘project_dependency_tree.txt’ is created.

$ cat project_dependency_tree.txt
com.sample.app:hello-world:jar:1
+- com.google.code.gson:gson:jar:2.8.5:compile
\- junit:junit:jar:4.12:test
   \- org.hamcrest:hamcrest-core:jar:1.3:test


Maven compiler plugin

Let us explore ‘maven compiler plugin’ to compile the sources of your project.

 

Example

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>


This plugin has two goals.

 

a.   compiler:compile is bound to the compile phase and is used to compile the main source files.

b.   compiler:testCompile is bound to the test-compile phase and is used to compile the test source files.

 

Maven clean plugin

The Clean Plugin is used when you want to remove files generated at build-time in a project's directory.

 

The Clean Plugin only has one goal.

 

clean:clean attempts to clean a project's working directory of the files that we're generated at build-time. By default, it discovers and deletes the directories configured in project.build.directory, project.build.outputDirectory, project.build.testOutputDirectory, and project.reporting.outputDirectory.

 

Example

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <verbose>true</verbose>
                </configuration>
            </plugin>


Updated pom.xml is given below

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sample.app</groupId>
    <artifactId>hello-world</artifactId>
    <version>1</version>

    <dependencies>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>


        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.1.2</version>
                <configuration>
                    <outputFile>project_dependency_tree.txt</outputFile>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <verbose>true</verbose>
                </configuration>
            </plugin>
            
        </plugins>
    </build>
</project>


Execute the command ‘mvn clean’ to confirms that the directories are deleted.

$ mvn clean
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------< com.sample.app:hello-world >---------------------
[INFO] Building hello-world 1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ hello-world ---
[INFO] Deleting /Users/krishna/eclipse-workspace/hello-world/target
[INFO] Deleting file /Users/krishna/eclipse-workspace/hello-world/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/maven-status/maven-compiler-plugin/compile/default-compile
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/maven-status/maven-compiler-plugin/compile
[INFO] Deleting file /Users/krishna/eclipse-workspace/hello-world/target/maven-status/maven-compiler-plugin/testCompile/default-cli/inputFiles.lst
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/maven-status/maven-compiler-plugin/testCompile/default-cli
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/maven-status/maven-compiler-plugin/testCompile
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/maven-status/maven-compiler-plugin
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/maven-status
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/classes
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/test-classes
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.391 s
[INFO] Finished at: 2020-10-24T18:43:25+05:30
[INFO] ------------------------------------------------------------------------


Maven jar plugin

This plugin provides the capability to build jars.

 

Example

            <plugin>
                <artifactId>maven-jar-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                        <configuration>
                            <classifier>test</classifier>
                        </configuration>
                    </execution>
                </executions>
            </plugin>


Updated pom.xml is looks like below.

 

pom.xml

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sample.app</groupId>
    <artifactId>hello-world</artifactId>
    <version>1</version>

    <dependencies>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>


        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.1.2</version>
                <configuration>
                    <outputFile>project_dependency_tree.txt</outputFile>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <verbose>true</verbose>
                </configuration>
            </plugin>

            <plugin>
                <artifactId>maven-jar-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                        <configuration>
                            <classifier>test</classifier>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>
</project>


Execute the command ‘mvn clean install’ to recompile and generate the jar file.

$ mvn clean install
[INFO] Scanning for projects...
[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.sample.app:hello-world:jar:1
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-jar-plugin is missing. @ line 58, column 12
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
[INFO]
[INFO] ---------------------< com.sample.app:hello-world >---------------------
[INFO] Building hello-world 1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ hello-world ---
[INFO] Deleting /Users/krishna/eclipse-workspace/hello-world/target
[INFO] Deleting file /Users/krishna/eclipse-workspace/hello-world/target/hello-world-1.jar
[INFO] Deleting file /Users/krishna/eclipse-workspace/hello-world/target/hello-world-1-test.jar
[INFO] Deleting file /Users/krishna/eclipse-workspace/hello-world/target/maven-archiver/pom.properties
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/maven-archiver
[INFO] Deleting file /Users/krishna/eclipse-workspace/hello-world/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/maven-status/maven-compiler-plugin/compile/default-compile
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/maven-status/maven-compiler-plugin/compile
[INFO] Deleting file /Users/krishna/eclipse-workspace/hello-world/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/maven-status/maven-compiler-plugin/testCompile
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/maven-status/maven-compiler-plugin
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/maven-status
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/classes
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target/test-classes
[INFO] Deleting directory /Users/krishna/eclipse-workspace/hello-world/target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello-world ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ hello-world ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ hello-world ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ hello-world ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ hello-world ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hello-world ---
[INFO] Building jar: /Users/krishna/eclipse-workspace/hello-world/target/hello-world-1.jar
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default) @ hello-world ---
[INFO] Building jar: /Users/krishna/eclipse-workspace/hello-world/target/hello-world-1-test.jar
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ hello-world ---
[INFO] Installing /Users/krishna/eclipse-workspace/hello-world/target/hello-world-1.jar to /Users/krishna/.m2/repository/com/sample/app/hello-world/1/hello-world-1.jar
[INFO] Installing /Users/krishna/eclipse-workspace/hello-world/pom.xml to /Users/krishna/.m2/repository/com/sample/app/hello-world/1/hello-world-1.pom
[INFO] Installing /Users/krishna/eclipse-workspace/hello-world/target/hello-world-1-test.jar to /Users/krishna/.m2/repository/com/sample/app/hello-world/1/hello-world-1-test.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.000 s
[INFO] Finished at: 2020-10-24T18:52:48+05:30
[INFO] ------------------------------------------------------------------------


Surefireplugin example

https://self-learning-java-tutorial.blogspot.com/2020/03/testng-run-test-cases-using-maven.html

 

spring-boot-maven-plugin example

https://self-learning-java-tutorial.blogspot.com/2019/09/specify-main-class-for-spring-boot.html

 

References

https://maven.apache.org/plugins/index.html

  

Previous                                                    Next                                                    Home

No comments:

Post a Comment