This is an XML format file that codifies all the information about a project including the plugins used to build the project and library (jar) dependencies.
The packaging element is part of the project information. The default is Jar but you can specify other formats such as WebARchive (WAR):
<packaging>war</packaging>
If Maven sees this it will download, if necessary, the WAR plugin and run it on the project. This plugin expects to find a certain directory structure as well as files such as web.xml
A major component of the POM is how it manages dependencies. Most Java projects depend either directly, or indirectly, on some external libraries, called JARs (Java ARchives). For example if we are using the Spring Java Persistence Api we would need to specify an dependency on this library in the POM. If the library doesn't exist in the repository Maven will download it and will add it to the Classpath.
<dependencies>
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jpa</artifactId>
<version>2.0.6</version>
</dependency>
</dependencies>
The example illustrates 3 key elements. The groupId and artifactId uniquely identify a specific project (in much the same way as our project uses these elements) and the version obviously identifies a particular build. In the example given there are a number of different projects under the org.springframework group such as spring, spring-core etc.
Dependencies can have subdependencies and so on. Maven will automagically load these dependant projects. However sometimes these subdependencies cause build problems if the project is not in the repository. If the funcationaly is not required it can be specifically removed using an Exclusion element. These Exclusions can also be used where we want to replace one package using the same Interfaces with another, say OpenJPA for Sun's JPA.
The scope element can limit the inclusion of a dependency to certain tasks. An example would be including dependencies required for testing in the Test phase.
The Maven project claims that dependencies get around the problem of Jar Hell or Jarmageddon. The automagic downloading of the required library version is a nice feature. The autoconfiguration of Classpaths for build, test etc is already possible via an ANT task. There are problems. Knowing exactly what your project depends on, both at build time and through dynamically loaded classes at run time. In the traditional Ant model you would download projects, unzip and dump the jars into a directory. With Maven you need to understand what the different artifactId contains and which version you require. Do I need spring, spring-core�
What generally happens is you compile you code, you get some missing symbols flagged by Maven. You then search the Maven repository and / or Google for the package name. It can get quite involved. Same process when you run the project if you haven't referenced all the dependencies. The following command can be quite useful:
mvn dependency:tree -Dincludes=org.springframework
for my project and the Spring framework above it gave the following dependency tree
[dependency:tree] com.abcseo:Magneato:war:0.1 +- org.springframework:spring:jar:2.5.4:compile \- org.springframework:spring-webmvc:jar:2.5.4:compile +- org.springframework:spring-beans:jar:2.5.4:compile +- org.springframework:spring-context:jar:2.5.4:compile +- org.springframework:spring-context-support:jar:2.5.4:compile +- org.springframework:spring-core:jar:2.5.4:compile \- org.springframework:spring-web:jar:2.5.4:compile
Which tells me that spring 2.5 depends on the webmvc jar which then has further dependencies.