Friday, July 31, 2015

Quick Overview of Basic Maven Concepts

This post is the third in the series of posts that Introduces Servlet based web application development in Java. It would be an overview of Maven and it serves to provide the necessary basic information about Maven before we proceed to other post in the series that touches on how to use Maven to package .war files and to use archetypes to create and deploy a .war to Tomcat.

An in depth coverage of these Maven concepts or Maven capabilities in general is not something that can be covered in a single blogpost; what this post does then is to only touch on some of the concepts, especially the ones that would help in making sense of the topics that will be addressed further on in this series of post.

If you are already familiar with these basic concepts, you can skip directly to the next post which shows how to use Maven archetypes to package and deploy a .war file.

What is Maven

Especially after reading Introduction to .war Packaging and Maven, a general feel of what Maven is and what it does should be established. Simply and informally put, you can see it as a tool that takes care of a lot of the processes involved in taking the source code, processing it, and make it available as a piece of software that is ready to be run or deployed. And the “lot of the process” part contains a handful: from managing dependencies, to compiling source codes, to providing documentation for a project, to helping with the packaging and release...the list goes on.

You can consult the Maven by example book for more introduction to Maven.

What is the POM

POM stands for Project Object Model and you can think of it as a model for a Maven project. The details of which is articulated in the pom.xml file. Which is where you specify the various parts of the Maven project, the dependencies, how the project is to be built, configurations etc. Obviously that is a simplified explanation. It still convey the spirit of what the POM is.

You can read more about the POM here: Introduction to the POM.

What Is Maven Plugin

This is straight forward, as the name itself is self explanatory: it is the mechanism by which we can hook into Maven and extend it.

What may not be self explanatory though, is the fact that the plugin architecture is at the very heart of how Maven works.

In fact, internally, most of the tasks Maven accomplishes are achieved via plugins. The Available Maven plugin page describes Maven thus “Maven is - at its heart - is a plugin execution framework; all work is done by plugins” So when Maven compiles your source code, or generates tests results, or perform any of its functionalities, there is a plugin behind the scenes responsible for this.

We have default plugins that comes standard with Maven, which are responsible for Maven's default behaviour, and we have trailer loads of Plugins out there that can be used to customize the behaviour of Maven. Here is a site that seeks to list available third party Maven plugins

What is Maven Coordinates

You most likely will not see Maven Coordinates being mentioned, but you would definitely run into things like GroupId, ArtifactId and Version...which are things, when taken together, constitutes the coordinate of a Maven artifact: artifact here referring to a piece of self contained software in the Maven lingo.

The coordinates then represent the identity of a Maven artifact. The combination of the GroupId, ArtifactId and Version is always unique. For example the Maven Coordinate for the Maven Compiler plugin, is

<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-compiler-plugin</artifactid>
<version>3.3</version>

which is unique and different from a 3.2 version of the same plugin:

<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>


What is a Maven Goal

Maven goal, refers to the specific functionality exposed by a plugin.

You can see a plugin as a Java Class, while it’s goals are the public methods that it exposes. And as each method of a class has a specific task it accomplishes when called, so also does Maven goals.

For example, Maven has an help plugin which can be used to view the platform specific information, or to view the current settings for Maven, or list profiles etc... These specific tasks the help plugin can be used to accomplish are its goals. You can see the complete list of the help plugin goals here

So if the goal is the functionality exposed by a plugin, how then do we execute them?

Executing a Maven Goal

You can execute a plugin’s goal via two means:

  • First by directly executing it via the command line, 
  • second by specifying that the goal be executed at a certain Maven Phase.

...and what is a Maven phase you may ask? Never mind yet, we would look into what they are soon enough, but now, we examine the first method of running a Maven goal: which is direct executing via command line/terminal.

For example let us say we want to execute the ‘system’ goal of the help plugin, we do this by running the following command in the command line

mvn help:system
So basically the syntax for executing a goal is
mvn plugin:goal [args]

The help plugin also comes with a goal (the describe goal) that can be used to view the list of goals in other plugins. For example if you want to see the list of goals in the Maven Compiler plugin, you can run

mvn help:describe -DgroupId=org.apache.maven.plugins -DartifactId=maven-compiler-plugin

So basically we pass the groupId and artifactId of the plugin we want to get its goals.

Running this on the maven compiler plugin would show us it has only three goals. compile, testCompile and help.

With that explained, let us look at what Maven phase is.

What is a Maven Phase

The factory production line will serve as a good metaphor to help us understand what the Maven Phase is.

The Maven build processes can be likened to a factory's production line, where products move on a conveyor belt, and get's built as it pass through the different phases of the manufacturing process.


Maven could also be seen to move a project's source code through a similar process. Where it passes it through distinct and different phases to be worked on, towards creating a complete artifact at the end of the process.

These phases are distinct and "named" in Maven, with distinct processes performed at each phase. So for example you would run into things like compile phase (the phase where the source is compiled) test phase (phase where the test is run) package (phase where the artifact is packaged up) etc…

And it is in these phases that we have another place where Maven plugins can be executed. (Apart from manually as already shown) In fact, Maven itself runs its default plugins at these phases to accomplish its tasks. This is so because Maven has lists of its default plugins automatically bound to some of the phases.

You can see the default plugin goals bound to each of the phases here

You can also use the mvn help describe goal to view the phase a plugin is bound to. For example to see the phases the goals in the maven compiler plugin are bound to, we run

mvn help:describe -DgroupId=org.apache.maven.plugins -DartifactId=maven-compiler-plugin -Ddetail

Which shows information about the goals, including the phase they are bound to.

If you have a goal in mind you can limit the result by including the goal in the command. for example

mvn help:describe -DgroupId=org.apache.maven.plugins -DartifactId=maven-compiler-plugin -Dgoal=compile -Ddetail

So basically this is what the phases are, but there is still one more concept we need to explore, and in order to do so, we still keep to the production line metaphor.

Looking at the production line it is obvious that we would have a collection of different production phases depending on the kind of product we want at the end of the day. For example a product that needs to be wrapped up in nylon cellophane might have a cellophane wrapping phase, while the one that needs to be packaged up in a box will have a boxing phase.

To produce product A, you will require a collection of phases that would be different to what would be needed to produce product B.

So also in Maven, these collection of phases is referred to as Maven lifecycle. And it is what is explained next.

What is a Maven Lifecycle

A Maven lifecycle is a collection of a Maven phase. It is as simple as that.

Maven itself comes with 3 default lifecycles. The clean lifecycle, the default lifecycle and the site lifecycle.

The 3 Maven Lifecycles:

Clean Lifecycle
Default (or Build) Lifecycle
Site lifecycle
Objective
To clean the workspace
To produce an artifact that can be installed or deployed
Generate html pages that documents the project

pre-clean
validate
pre-site

clean
initialize
site

post-clean
generate-sources
post-site


process-sources
site-deploy


generate-resources



process-resources



compile



process-classes



generate-test-sources



process-test-sources



generate-test-resources



process-test-resources



test-compile



process-test-classes



test



prepare-package



package



pre-integration-test



integration-test



post-integration-test



verify



install



deploy


So what can you do with the Maven Lifecycles? Nothing! You cannot run the lifecycles. They are just a logical collection of Maven phases. What you can do though, is to run any of the build phases in a lifecycle. And in Maven, running any build phase would ensure that all the build phase before the one you run is also executed.

For example if you run the last phase in the default (build) lifecycle thus:

mvn deploy

Maven will ensure that all the goals bound to all the previous phases before the deploy gets executed.

You can also run any phase in a lifecycle not necessary the last one. For example running

mvn clean

or

mvn site

is running the second phase in the clean lifecycle and site lifecycle respectively.

I purposely used mvn clean and mvn site as an example as I initially, wrongly thought this to mean that the clean lifecycle or site lifecycle is being run which lead me to search for how to also run the default lifecycle...but as I said earlier on, you cannot run a lifecycle, just the phases in a lifecycle and mvn clean is running the second phase in the clean lifecycle not running the clean lifecycle itself.

As stated, Maven goals can be executed in the different Maven Phases, but apart from the default bindings, Maven also provide us a mechanism of specifying the Maven goals we would want to run at a Maven Phase. This mechanism is the way for us to plug in into the Maven phases and customize what happens at each phase by specifying Maven goals we would want executed at that phase.

For example we can use the run goal in maven-antrun-plugin to print out messages to the console at different phases. We would hook into the validate, compile and package phases to print out messages.

The following snippet that would have to go in the pom.xml will achieve this


    
        
            maven-antrun-plugin
            
                
                    validate
                    
                        run
                    
                    
                        
                            Hello world! From the validate phase
                        
                    
                

                
                    compile
                    
                        run
                    
                    
                        
                            Hello world! From the compile phase
                        
                    
                

                
                    validate
                    
                        run
                    
                    
                        
                            Hello world! From the validate phase
                        
                    
                

            
        
    
    


The above snippets shows how to use the <execution/> element to customize the goals that get executed at a particular Maven phase.

And that concludes the brief overview of some of the Maven concepts that would help in following what comes next which is the actual steps of using Maven Archetypes to package and deploy .war Files to Tomcat.

Next Post: How to package and deploy .war Files to Tomcat via Maven Archetypes
Previous Post: Introduction to .war Packaging and Maven

Additional Resources

No comments: