In this article I will give you a basic introduction to Maven, what it is good for and how you can use it to create your own projects and maintain its dependencies with an ease.
What is Maven?
Maven is a tool for developers to enable full control of the build life-cycle. With the usage of Maven a project can automate its build infrastructure and make sure that every developer uses the same base of dependencies (external libraries) in the same version as everyone does. This reduces the problems which can occur in production (or test environments) based on the different libraries (or just different versions) used.
With Maven you cannot just automate the build process but you can generate reports, use static code analysis, maintain releases and so on.
The idea behind Maven
If you have ever used Ant you may know that when you build a project you have had to configure everything: where the source folders are, where the compiled files should be placed, where are the dependent libraries (only the file name was of matter — if you did not have the version in the name you could use anything and every developer had to be careful)… And so on. And this was a very good tool at times prior Maven because it automated you build process.
But then Maven came up with a new idea: “Convention over Configuration”. This idea means that Maven expects a specified folder-structure for your project (convention) and uses this information to leverage you of the task of configuration.
This means that for Maven the sources have to be under the <project home folder>/src/main
folder, tests in the <project home folder>/src/test
. Because Maven is based on Java we can go a step further and say that all Java sources have to be under <project home folder>/src/main/java
and all application specific resources under <project home folder>/src/main/resources
. The generated files will be stored per convention in <project home folder>/target
.
And because of this developers can write easily extensions to the basic Maven life-cycle which you can add to your project and use them with ease.
The Project Object Model
The Project Object Model defines the main structure of your Maven project. It can be found in the pom.xml
file which is required to be present in your <project home folder>
. This file can contain beside the basic information (project ID, version) the following:
- project dependencies
- build-helper plugins
- goals
- build-execution profiles
- developers
The project ID is made of the groupID and the artifactID which helps to uniquely define our project. Most of the time the groupID is the reversed company domain name, the artifactID is the name of the project.
Let’s have a minimalistic and working example for a pom.xml
file:
4.0.0
hu.japy.dev
maven-example
1.0
Looks really very minimalistic, don’t it?
The magic lies in Maven: every pom.xml
inherits basic configuration from a so called super POM where basic stuff is defined like compiler plugins, source and target directories and so on. I will omit this lengthy result here but if you are interested you can look at it with the following command:
mvn help:effective-pom
Dependency management and repositories
Maven comes with automated dependency management. This means you only have to define the dependency to use in your application and Maven gathers is from a repository
Creating projects
To create a simple Maven project without any content and without the use of any basic blueprint you can execute the following command in your console:
mvn archetype:generate -DgroupId=your.group.id -DartifactId=your.artifact.id -DinteractiveMode=false
This will generate a simple project structure. Applying this command to fit the previous pom.xml
we would get the following project structure:
Naturally you can use an archetype for creating a project. If we change the following command to this one:
mvn archetype:generate -DgroupId=hu.japy.dev -DartifactId=maven-example -DinteractiveMode=false -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.1
we will get a project which already has some basic code and the following structure:
As you could see we used in this case an archetype: maven.archetype-quickstart
which is a blueprint for a simple application which gives us some code to get started with.
Archetypes
Archetypes are the Maven blueprints. Some companies created own blueprints to enable developers to quickly start with their tools by packing up the required dependencies into a template which can be converted to a project (with a pom.xml
and optinal Java code).
If you enable interactive mode when you create a project then you can see the available archetypes you can use with your project. Currently there are 1424 available:
The one with the number 1425 was created by me and is not publicly available. But as you might guess you can create your own archetype. This gives sense if you have to create the same project with the same settings over and over again.
Starting a Maven build
To start a Maven build you have to enter your <project home folder>
and execute the right Maven command. Right command means that you not only have to call mvn
(the command for running Maven) but you have to specify a life-cycle phase too.
The major phases developers are using most of the time are the following:
compile
: compiles the source files intotarget/classes
package
: packages up the whole application and puts this package into thetarget
folderinstall
: installs the package into your local Maven repository.
Naturally this is not the whole list of phases. There are pre and post phases for each phase and some phase executes all phases up to and inclusive that phase.
For example if you execute
mvn install
Then all phases up to install
, so compile and package too (naturally there are a lot of phases before install
but to list all would exceed the bounds of this article).
An example
Let’s package up the example from the previous section (where we used the archetype) and let’s run the resulting application.
maven-example $ mvn clean package
This gives a lot of information messages about compiling and testing the code but at the end you should see something like this in your console:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
This means that the build succeeded and you have a JAR file in the target
folder of the project. This means we can run the application. To do this execute the following command from your <project home folder>
:
maven-example $ java -cp target/maven-example-1.0-SNAPSHOT.jar hu.japy.dev.App
Hello World!
If we try to run only the JAR file we would get an exception because there is no entry in the MANIFEST.MF
file of the package to tell Java which class contains the main
method to start the application.
In a later article I could write a solution on this problem but you might guess it is not as complicated as it sounds.
Conclusion
Maven is a powerful tool which enables you to create a project faster than with Ant or other build tools where you have to configure a lot of things. It uses conventions to have your project set-up quickly.
It gives you dependency management where you can easily maintain the project’s dependencies across all developers — and this means you can keep everyone use the same version.
Naturally this introductory article cannot cover everything about Maven. There is a lot more you can look at: packaging, build profiles, automated test execution, deployment and many more. With the usage of Maven you can easily harness other libraries than Hibernate and Spring to have a complex application working.