My last article on maven described maven basic setup. This article covers basic concepts of maven self.
Maven is a project management framework (or tool).
This definition is quite abstract and don’t justifies the richness and complexity of Maven. It turns out often it’s not easy to describe software tools. So the idea of Software is central element. The effort was to adopt best practices let’s say principles:
- Convention over configuration
- Declarative execution
- Reuse of build logic
- Coherent organization of dependencies
Let’ see how maven adopts these. Here are the key concepts maven provides:
- Set of build standards
- Standard life cycles for building, testing and so on
- Default Tasks
- Common declarative Project Object Model (POM)
- Dependencies description and management
- Artifact repository
- Modular Design (Plug-ins)
Maven provides a comprehensive model that can be applied to all software projects. That model uses a common project “language”, and the software tool is just a supporting element within this model.
Maven is not like Ant
Because i’m was long time a Apache Ant user (and still i am) it’s important for me to emphasize some key differences in maven philosophy.
- Pre-defined (non just project wide) build standards, with pre-defined default life cycles, directory layout and more. Can say maven has predefined assumptions how to build your project (I don’t say that i like it in any sence)
- It’s possible to build any given project without having to understand how the individual plug-ins works.
- Maven provides declarative style. Instead of defining procedures your configure it.
That is in general. Let’s look deeper where and how the configuration is done.
Maven Project Object Model (POM)
A File named pom.xml is XML representation of “Project Object Model” an always a central place of any maven project. We can think of it as maven project definition file. Or as maven POM Reference states
It is a one-stop-shop for all things concerning the project. In fact, in the Maven world, a project need not contain any code at all, merely a pom.xml
In dedail every Project has basics…
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.codehaus.mojo</groupId> <artifactId>my-project</artifactId> <version>1.0</version> <packaging>jar</packaging> </project>
These three elements defines the ID of an artifact and in effect of the particular build results.
- parent – Define inheritance to parent project.
- modules – declares child modules.
- dependencies – Dependencies of a project.
- dependencyManagement – allows maintenance application-wide dependency maintenance.
- Project Information (For human eyes, no meaning for maven)
- Build Settings: Changes in Lifecycles done here.
- finalName – suitable for artifact name
- resources – used for configuration of resource paths and destinations.
- plugins - allows registration and configuration of custom build-steps.
- Environment Settings
- ciManagement – Continous Integration management.
- scm – Source Revision Control Systems configuration.
- repositories – artefat repositories configuration.
- pluginRepositores – is here to define separate repositories for Maven Plugins (not used widely)
- distributionManagement – manges distribution on releases.
The POM-Tree gives a quick overview, what it ist all bout. Of course you don’t have to be familiar with all that parts of the tree. It ist usual to start working with simple pom and extending it step by step if default behavior is not sufficient. Therefore pom.xml represents static project configuration, let’s look how this configuration apply on build-time.
Lifecycle is essential concept of maven. There are tree pre-defined Lifecycles Clean, Build and Site. Please read Lyfecycle Refence for more details. Every lifecycle defines an ordered set of Phases. If Clean-Lifecycle and Site-Lifecycle defines 3 and 4 Phases respectively. The main Build-Lifecycle has 23!:
These build phases are executed sequentially in the given order. To do all those, you only need to call the last build phase to be executed, in this case, deploy:
will execute all phases except deploy and do on. It is also possible to call phases of different lifecycles e.g.
mvn clean install
this command will traverse into all of the lifecycles and run clean including all of the prior steps then install in the same way.
A Goal represents a specific task (finer than a build phase) which actually caries out the amount of work.
- A goal may be bound to zero or more build phases. If a build phase has no goals bound to it, that build phase will not execute
- A goal not bound to any build phase could be executed outside of the build lifecycle by direct invocation
mvn clean dependency:copy-dependencies package
dependency:copy-dependencies is an unbound goal, which is executed as it is. clean and package are phases and executed like phases with predecessors.
Moreover, if a goal is bound to one or more build phases, that goal will be called in all those phases.
Therefore it’s getting essential to know how that Built-in Lifecycle bindings between phases and goals looks like. And then to know how are binding to the default plugins. In the Lifecycle List above you can see all the default bounded goals. Effectively these goals are executed every time in default configuration.
So it helps to know where to find the configuration information about them. Here ist the short list:
Basic Bindings for Build-Lifecycle
Below are the default life-cycle bindings for the jar packaging.
Phase Goal Plugin Description process-resources resources:resources maven-resources-plugin Copy non-source-code resources to the staging directory. compile compiler:compile maven-compiler-plugin Compile project source code to the staging directory. process-test-resources resources:testResources maven-resources-plugin Copy non-source-code test resources to the test output directory for unit-test compilation. test-compile compiler:testCompile maven-compiler-plugin Compile unit-test source code to the test output directory. test surefire:test maven-surefire-plugin Execute unit tests. package jar:jar
The defautl goal depends on POM packaging attribute. Default packaging is jar result in goal jar:jar. install install:install maven-install-plugin Install the jar archive into the local Maven repository. deploy deploy:deploy maven-deploy-plugin Deploy the jar archive to a remote Maven repository.
Profiles are specify some subset of POM definition. Piratically profiles modify the POM at build time, and are meant to be used to give context dependent parameters. Fro example they allow to define test and production context without creating several different POM definitions. Profile-definitions is defined inside of pom.xml or settings.xml following same inheritance rules as the rest of POM file (read above).
Profiles can be used explicitly form command line
mvn groupId:artifactId:goal -P profile-1, profile-2
or defined as default active inside settings.xml
<settings> ... <activeProfiles> <activeProfile>profile-1</activeProfile> </activeProfiles> ... </settings>
But in case of pom definition it is considerable to use use “smart activation” of a profile. Example below show’s example profile definition which will be activated automatically on apple mac computers. The defined Profiled with id default_mac only set property:
<profile> <id>default_mac</id> <activation> <os> <family>mac</family> </os> </activation> <properties> <build.style>Macintosh</build.style> </properties> </profile>
Check more examples.
I hope this helps someone to go quick and dirty familiar with maven. For details pleas ask questions or see following resources.