Unit 6 - Notes
INT331
Unit 6: Working with Maven
1. Introduction to Maven
What is Maven?
Apache Maven is a comprehensive software project management and comprehension tool. Based on the concept of a Project Object Model (POM), Maven can manage a project's build, reporting, and documentation from a central piece of information.
While primarily used for Java projects, Maven can also be used to build and manage projects written in C#, Ruby, Scala, and other languages.
Key Objectives of Maven
- Making the build process easy: It creates a standard way to build projects.
- Providing a uniform build system: It allows developers to move between projects without learning a new build structure.
- Providing quality project information: It manages changelogs, dependency lists, unit test reports, and mailing lists.
- Encouraging better development practices: It enforces modular design and separates source code from build outputs.
Maven vs. Ant
- Ant: A procedural tool. You must write scripts to tell Ant exactly what to do and when to do it (e.g., "create directory X, then compile Y, then copy Z").
- Maven: A declarative tool. You tell Maven what you want (e.g., "I want a JAR file"), and Maven uses its built-in lifecycle and logic to achieve that result using standard conventions.
2. Maven Project Structure (Standard Directory Layout)
Maven relies heavily on the principle of "Convention over Configuration." This means that if you follow standard directory layouts, you do not need to configure paths manually in build scripts.
The Standard Layout
A typical Maven project looks like this:
my-app/
├── pom.xml (The Project Object Model file)
├── src/
│ ├── main/
│ │ ├── java/ (Application/Library source code)
│ │ ├── resources/ (Config files, images, properties)
│ │ └── webapp/ (Web application sources: JSP, WEB-INF - if applicable)
│ └── test/
│ ├── java/ (Unit test source code)
│ └── resources/ (Test-specific resources)
└── target/ (Generated artifacts: compiled classes, JARs, WARs)
Explanation of Directories
- pom.xml: Located at the root. It contains all configuration settings.
- src/main/java: Contains the production source code.
- src/main/resources: Contains resources needed at runtime (e.g.,
log4j.properties,application.yaml). These are copied to the classpath output. - src/test/java: Contains test code (e.g., JUnit tests). These are compiled but not included in the final distribution artifact.
- target: This directory is generated by Maven. It contains all temporary build files and the final artifact (e.g.,
my-app-1.0.jar). Runningmvn cleanremoves this directory.
3. Project Object Model (POM)
The POM is the fundamental unit of work in Maven. It is an XML file named pom.xml that resides in the base directory of the project. It contains information about the project and configuration details used by Maven to build the project.
Maven Coordinates (GAV)
Every Maven project is uniquely identified by three coordinates:
- groupId: A unique base name of the company or group that created the project (e.g.,
com.google,org.apache.maven). It usually follows the reverse domain name syntax. - artifactId: The unique name of the project/module (e.g.,
maven-core,junit). - version: The version of the project (e.g.,
1.0.0,2.5-SNAPSHOT).
Basic Structure of 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
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging> <!-- Default is jar, can be war, ear, pom -->
<name>My Application</name>
<description>A simple Maven project</description>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- External libraries defined here -->
</dependencies>
</project>
The Super POM
All POMs inherit from a parent POM. If no parent is defined, they inherit from the Super POM. This is where defaults are defined (like the default directory structure, standard plugins, and central repository URL).
4. Maven Build Lifecycle
The build lifecycle is a sequence of defined phases that define the order in which goals are executed. When you run a Maven command, you are essentially invoking a specific lifecycle phase.
The Three Built-in Lifecycles
1. The Clean Lifecycle
Handles project cleaning.
- pre-clean: Execute processes needed prior to the actual project cleaning.
- clean: Remove all files generated by the previous build (deletes the
targetfolder). - post-clean: Execute processes needed to finalize the project cleaning.
2. The Default (Build) Lifecycle
This is the main lifecycle responsible for deploying the project. The most common phases (in order) are:
- validate: Validate the project is correct and all necessary information is available.
- compile: Compile the source code of the project (
src/main/java). - test: Test the compiled source code using a suitable unit testing framework (
src/test/java). These tests should not require the code be packaged or deployed. - package: Take the compiled code and package it in its distributable format, such as a JAR or WAR.
- verify: Run any checks on results of integration tests to ensure quality criteria are met.
- install: Install the package into the local repository, for use as a dependency in other projects locally.
- deploy: Done in the build environment, copies the final package to the remote repository for sharing with other developers and projects.
Note: Executing a phase automatically executes all preceding phases. For example, running mvn install will automatically run validate, compile, test, package, and verify before installing.
3. The Site Lifecycle
Handles the creation of project documentation.
- pre-site
- site: Generates the project's site documentation.
- post-site
- site-deploy: Deploys the generated site documentation to the specified web server.
5. Maven Repository
A repository in Maven is a directory where all the project jars, library jars, plugins, or any other project specific artifacts are stored and can be used by Maven easily.
Types of Repositories
1. Local Repository
- Location: Usually located in your computer's user folder:
~/.m2/repository. - Function: It is a cache. When Maven needs a dependency, it looks here first. If found, it uses it. If not, it downloads it from the central repository and stores it here for future use.
2. Central Repository
- Location: Hosted on the internet by the Maven community (Maven Central).
- Function: It contains a massive collection of commonly used libraries (Spring, Hibernate, Apache Commons, etc.). Maven automatically consults this repository if a dependency is not found locally.
3. Remote (Internal) Repository
- Location: A repository set up by a company on their local network (e.g., using Sonatype Nexus or JFrog Artifactory).
- Function: Used to host private artifacts proprietary to the company. It acts as a proxy between the developers and the Central Repository to improve speed and control security.
Dependency Search Mechanism
When Maven builds a project:
- Scans
pom.xmlfor dependencies. - Checks the Local Repository.
- If not found, checks the Central Repository (or Remote Repository if configured).
- Downloads the artifact to the Local Repository.
- Uses the artifact for the build.
6. Maven Dependencies
Dependencies are external Java archives (JARs) that your project requires to compile, test, or run.
Defining Dependencies
Dependencies are listed in the <dependencies> section of the pom.xml.
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
Dependency Scopes
The scope controls when a dependency is included in the classpath (during compilation, testing, or runtime).
- compile (default): Available in all classpaths (compile, test, run). Propagated to dependent projects.
- provided: Needed for compilation and testing but provided by the runtime environment (e.g., Servlet API provided by Tomcat). Not included in the final artifact.
- runtime: Not required for compilation, but required for execution (e.g., JDBC Drivers).
- test: Only required for compiling and running tests (e.g., JUnit, Mockito). Not included in the final artifact.
- system: Similar to provided, but you must specify the path to the JAR on the local file system (generally discouraged).
Transitive Dependencies
This is a powerful feature of Maven. If Project A depends on Project B, and Project B depends on Project C:
- Project A automatically gains access to Project C.
- Developers do not need to manually find and include the libraries that their dependencies need.
Dependency Management
If a conflict arises (e.g., two dependencies require different versions of the same library), Maven uses "Dependency Mediation" to decide which version to use (usually the "nearest definition" strategy).
7. Maven Plugins
Maven is essentially a plugin execution framework. All work (compiling, testing, packaging) is done by plugins.
Concepts
- Plugin: A collection of goals.
- Goal: A specific task that contributes to the building and managing of a project.
Binding Goals to Lifecycle Phases
The standard lifecycle phases are essentially bindings to specific plugin goals.
- compile phase -> executes
compiler:compilegoal. - test phase -> executes
surefire:testgoal. - package phase -> executes
jar:jar(orwar:war) goal.
Common Plugins
- maven-compiler-plugin: Compiles the Java sources. Allows specifying the JDK version.
- maven-surefire-plugin: Runs the unit tests and generates reports.
- maven-jar-plugin: Creates the JAR file from the compiled classes.
- maven-war-plugin: Creates a WAR file for web applications.
- maven-clean-plugin: Cleans the target directory.
Configuring a Plugin
Plugins are configured in the <build> section of the pom.xml.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>