Maven

Li

Li Wei

May 19, 202411 min read

Maven

Overview

What is MVN?

Maven is essentially a project management tool that abstracts the development and management process into a Project Object Model (POM).

POM: Project Object Model. Maven is written in Java and manages everything in an object‑oriented way, ultimately treating a project as an object called a POM.

pom.xml: Maven requires a pom.xml file. By loading this configuration file, Maven can learn the project's information; the file represents a single project. If you have eight projects, you will have eight pom.xml files.

Dependency management: Maven manages all the resources a project depends on. The relationship is bidirectional: a project can declare the resources it needs, and when other projects depend on yours, Maven also treats your project as a managed resource.

Storage locations for managed resources: local repository, private repository, central repository.


Main functions:

  • Project building: Provides a standard, cross‑platform way to automate builds.
  • Dependency management: Conveniently manages project dependencies (JAR files) and avoids version conflicts.
  • Unified development structure: Supplies a standard, consistent project layout.

Directory purpose summary:

  • src/main/java: Java source code.
  • src/main/resources: Configuration files (e.g., MyBatis configs, XML mappers, custom config files).
  • src/main/webapp: Web resources (HTML, CSS, JS, etc.).
  • src/test/java: Test code.
  • src/test/resources: Test‑related configuration files.
  • src/pom.xml: Project’s POM file.

Core Concepts

Repository: Stores resources, mainly JARs. Types include local repository, private repository, and central repository (the latter two are remote).

  • Central repository: Maintained by the Maven team; it is open source.
  • Private repository: Used within a company/department to store resources. It can also proxy the central repository. Purposes:
    • Store copyrighted resources (purchased or internally developed JARs).
    • Share resources internally while keeping them private externally.
  • Local repository: Resides on a developer’s machine; can also fetch resources from remote repositories.

Coordinates: In Maven, coordinates describe the location of a resource in a repository.

  • Purpose: Provide a unique identifier so that machines can locate and download the resource automatically.
  • Lookup: Use https://mvnrepository.com to search for a resource’s coordinates by name.
  • Dependency elements:
    • groupId: The organization or domain (usually reversed, e.g., org.mybatis).
    • artifactId: The name of the resource (often the project or module name, e.g., crm, sms).
    • version: The resource’s version.
    • packaging: How the resource is packaged; common values:
      • jar (Java Archive) – default.
      • war (Web Application Archive).
      • pom – indicates a parent POM (used for multi‑module projects); only a pom.xml is generated, no JAR or other package.

Environment Setup

Configuration

Maven website: http://maven.apache.org/

Directory layout:

  • bin: Executable programs.
  • boot: Maven’s own bootstrap loader.
  • conf: Maven configuration files.
  • lib: Libraries required for Maven runtime.

Set MAVEN_HOME:

Add to Path: %MAVEN_HOME%\bin

After configuring environment variables, test the setup by running the following command in a DOS window: mvn -v

Repository Configuration

By default, Maven’s local repository is located at .m2/repository in the user’s home directory. To change its location, edit Maven’s settings file conf/settings.xml.

  • Change local repository location: Find the <localRepository> tag and modify its default value.
    Note: A settings.xml file should also exist in the same directory as the repository (.m2) – local user settings take precedence over global settings.

  • Global settings.xml defines Maven’s common configuration.

  • User settings.xml defines the current user’s configuration.

  • Change remote repositories: Locate the <mirrors> tag in the settings file and add a domestic mirror under it.

  • Change default JDK: Find the <java> tag and add the appropriate configuration.


Project Creation

Manual Setup

  • Create a Maven project directory project-java and navigate into it.

  • Create the Java source directory: src/main/java.

  • Create the configuration files directory: src/main/resources.

  • Create the test source directory: src/test/java.

  • Create the test resources directory: src/test/resources.

  • In src/main/java create a package (on Windows this means creating a folder) demo, and inside it create the file Demo.java containing the demo Java program shown below.

    • In src/test/java create a test package (folder) demo, and inside it add the test program DemoTest.java.

    • In **project-java/src** create **pom.xml** file with the following format:

    • After the structure is ready, build the project with Maven. Maven commands start with mvn; additional goals are added as space‑separated parameters, allowing multiple goals to run in one line.

      • mvn compile – compile
      • mvn clean – clean
      • mvn test – test
      • mvn package – package
      • mvn install – install to the local repository

    Note: Running any goal will also execute all preceding goals.

IDEA Setup

Without Archetype
  • Configure Maven in IDEA, selecting Maven 3.6.1 to avoid dependency issues.
  • Create a Maven project: New Module → Maven → leave Create from archetype unchecked.
  • Fill in the project coordinates:
    • GroupId: demo
    • ArtifactId: project-java
  • Verify that directory colors are correct.
  • In IDEA’s right‑hand panel, open Maven ProjectLifecycle.
  • Add custom Maven commands: Run → Edit Configurations → click +Maven.
Using an Archetype

Standard project:

  • When creating a Maven project, choose an archetype (template).
  • After creation, some directories may be missing; add them manually and mark them appropriately.

Web project:

  • Choose a web‑related archetype (those starting with “Maven” are simplified).

  • The generated structure will be incomplete; add the missing directories and mark them correctly.

  • To run the web project, add the Tomcat plugin coordinates in pom.xml:

    • After configuring the plugin, you’ll see it in IDEA’s right‑hand panel maven-project and can start the project via web01 → Plugins → tomcat7 → tomcat7:run.

Dependency Management

Declaring Dependencies

A dependency is a JAR required at runtime. The declaration format is:

<dependency>
    <groupId>...</groupId>
    <artifactId>...</artifactId>
    <version>...</version>
    <!-- optional: <scope>...</scope> -->
</dependency>

Transitive Dependencies

Dependencies are transitive and fall into two categories:

  • Direct dependencies: Declared explicitly in the current project.
  • Indirect (transitive) dependencies: Dependencies of your dependencies.

Conflict resolution rules (when transitive dependencies clash):

  1. Nearest‑first (path priority): The deeper the dependency in the tree, the lower its priority.
  2. Declaration order: When at the same depth, the earlier declaration wins.
  3. Special priority: When the same version is declared at the same level, the later declaration overrides the earlier one.
  • Optional dependency: Hides the dependency from downstream projects (non‑transparent).
  • Exclusion: Actively removes a transitive dependency; no version needs to be specified.

Dependency Scope

By default, a JAR is available everywhere. The <scope> tag (scope) can limit its visibility:

  • compile – available in the main source (src/main).
  • test – available only in test source (src/test).
  • provided – needed for compilation but not packaged.
  • runtime – needed at runtime but not for compilation.

The <scope> tag accepts four values: compile,test,provided,runtime.

Scope transitivity: (details omitted in source)


Build Lifecycle

Key Phases

Maven’s build lifecycle describes the sequence of phases a build goes through. The most common flow:

compile → test-compile → test → package → install

  • clean: Cleanup work.

    • pre-clean: Tasks before cleaning.
    • clean: Remove all files from the previous build.
    • post-clean: Tasks immediately after cleaning.
  • default: Core work (compile, test, package, deploy, etc.). Each phase automatically runs all preceding phases.

  • site: Generate reports and publish a site.

    • pre-site: Tasks before site generation.
    • site: Generate the project site.
    • post-site: Tasks after site generation, preparing for deployment.
    • site-deploy: Deploy the generated site to a server.

Executing Phases

Maven plugins are bound to lifecycle phases. When a phase is reached, the associated plugin runs. Maven ships with default plugins bound to each phase, and you can add custom plugins as needed.


Module Development

Splitting

Dividing a project into modules:

  • ssm_pojo

    • Create a new module and copy the original project’s POJO classes (e.g., User). No configuration files needed.
  • ssm_dao

    • Create a new module and copy data‑layer interfaces (e.g., UserDao) and related config files (3 files). Keep the pagination plugin configuration tied to SqlSessionFactoryBean. The pom.xml should only include data‑layer dependencies (remove Spring MVC ones).
    • Dependencies: directly depend on ssm_pojo (run install on ssm_pojo to put it in the local repo).
  • ssm_service

    • Create a new module and copy service interfaces/implementations (e.g., UserService, UserServiceImpl) and one data‑layer config file. pom.xml should include data‑layer dependencies (remove Spring MVC).
    • Dependencies: directly depend on ssm_dao (install it locally) and indirectly on ssm_pojo (via ssm_dao).
    • Rename the Spring core config file to include the module name, e.g., applicationContext-service.xml.
  • ssm_controller (web layer)

    • Create a new module using the webapp template and copy controller classes (e.g., UserController) and related config files (1 presentation‑layer config, 1 server config).
    • pom.xml should include only web‑related dependencies (remove Spring MVC from previous modules).
    • Dependencies: directly depend on ssm_service (install it locally) and indirectly on ssm_dao and ssm_pojo.
    • Update web.xml to load all Spring contexts using the * wildcard (loads any file starting with applicationContext-).
    • Add the Spring MVC dependency.

Aggregation

Purpose: Quickly build a Maven project that consists of multiple modules in one go.

How to create:

  • Create an empty module with packaging type pom.
  • List the modules to be built together under <modules>.

Note: Execution order of aggregated modules depends on their inter‑module dependencies, not on the order they appear in the POM.

Inheritance

Maven inheritance works like Java inheritance: a child module can reuse configuration from a parent.

  • dependencyManagement only declares dependencies; child modules must explicitly list the dependencies they need.
  • If a child does not declare a dependency, it will not inherit it.
  • If a child declares a dependency without a version, the version (and scope) are inherited from the parent.
  • If the child specifies a version, that version overrides the parent’s.

How to set up:

  • In the child module, declare the parent’s coordinates and relative path.
  • Define managed dependencies in the parent’s dependencyManagement.
  • In the child, declare dependencies without versions; they will be resolved from the parent.

Inheritance vs. Aggregation:

  • Purpose

    • Aggregation: Build multiple projects together quickly.
    • Inheritance: Share configuration quickly.
  • Similarity

    • Both use a pom packaging type and can be combined in a single POM.
    • Both are design‑time constructs; they contain no actual code.
  • Differences

    • Aggregation is defined in the current module and knows which modules participate.
    • Inheritance is defined in the child; the parent does not know which children inherit from it.

Properties

Keeping versions consistent is crucial.

Property categories:

  • Custom properties
  • Built‑in properties
  • Settings properties
  • Java system properties
  • Environment variable properties

Custom properties

  • Purpose: Define variables for centralized maintenance.
  • Format:
<properties>
    <my.property>value</my.property>
</properties>
  • Usage: ${my.property}

Built‑in properties

  • Purpose: Use Maven’s predefined properties for quick configuration.
  • Usage: ${project.version}, ${java.version}, etc.

Settings properties

  • Pulled from settings.xml tags; useful for dynamic configuration.
  • Usage: ${settings.localRepository}, etc.

Java system properties

  • Purpose: Read Java system properties.
  • Usage: ${java.home}, etc.
  • Query via command line: cmd /c "echo %JAVA_HOME%"

Environment variable properties

  • Purpose: Use environment variables.
  • Usage: ${env.PATH}, etc.
  • Query via command line: echo %PATH%

Project Versions

SNAPSHOT (development version):

  • Used during active development to allow team members to share and update modules frequently.
  • SNAPSHOT versions are continuously updated as development progresses.

RELEASE (stable version):

  • After reaching a milestone, a stable version is released. The artifact is immutable; further development does not alter this released version.

Versioning convention:

  • Major: Significant architectural changes (e.g., Spring 5 vs. Spring 4).
  • Minor: Large feature additions or systematic bug fixes.
  • Patch: Minor bug fixes.
  • Milestone: Pre‑release version indicating an internal checkpoint; less stable than the subsequent official release.

Resource Filtering

Purpose: Load properties defined in the POM into any configuration file.

  • Parent POM: pom.xml
  • Enable filtering in the build section and reference properties in resource files using ${property.name}.

Multi‑Environment Configuration

Load environment‑specific settings:

  • Define profiles in pom.xml for each environment.
  • Activate a profile to load its configuration.
  • Example usage: mvn clean install -Pdev

Skipping Tests

Command:

mvn install -DskipTests

Note: The command’s lifecycle must still include the test phase for the flag to have effect.

IDEA interface: (screenshot placeholder)

Configure skipping in the IDE settings as needed.


Maven Private Repository

Nexus

Nexus is a Maven repository manager from Sonatype.

Download: https://help.sonatype.com/repom

(content truncated)


Originally written by Li Wei (李唯_) and published in Chinese on 后端技术栈全书 (Full-Stack Backend Engineering). Translated and adapted for DriftSeas with permission.

Keep reading

More related articles from DriftSeas.