Maven
What is Maven
Maven is a project management and build automation tool widely used by Java developers to simplify development workflows. It uses a centralized Project Object Model (POM) to manage build processes, dependencies, and project configurations efficiently.
The Maven Build Automation tool provides a lot of features to make the development easy.
- Dependency Management: Automatically downloads and manages external libraries.
- Standard Project Structure: Follows a fixed folder layout for source, test, and other files.
- Build Lifecycle: Defines standard build phases like compile, test, and deploy.
- Plugins: Supports plugins for compiling, testing, packaging, and more.
- POM File: Uses pom.xml to manage configuration and dependencies.
- Central Repository: Fetches dependencies from a shared online repository.
- Build Profiles: Supports different settings for dev, QA, and production.
- Reporting: Can generate Javadoc, test reports, and project documentation.
- IDE Support: Integrates with Eclipse, IntelliJ, NetBeans, etc.
The problems that Maven solved:
- Getting right JAR files for each project as there may be different versions of separate packages.
- To download dependencies visiting of the official website of different software is not needed. We can just visit mvnrepository.com.
- Helps to create the right project structure which is essential for execution.
Maven Build Life Cycle
The Default Lifecycle is the most commonly used lifecycle, focusing on the build process from validation to deployment. Phases in this lifecycle are as follows:
- Validate: This phase is responsible for validates if the project structure is correct or not.
- Compile: It compiles the source code, converts the .java files to .class, and stores these classes in the target/classes folder.
- Test: It runs unit tests for the maven project
- Package: This phase is responsible for distribute compiled code in the format of WAR, JAR and others.
- Integration test: It runs the integration tests for the maven project
- Verify: verify that the project is valid and meets the quality standards.
- Install: This phase is responsible for install packaged code on the system.
- Deploy: copies the packaged code to the remote repository for deployment then other developers can easily access this one.
The Clean Lifecycle is designed for cleaning the project, ensuring that artifacts generated from previous builds are removed before starting the new build process. Phases in the Clean Lifecycle:
- pre-clean: Executes processes before cleaning.
- clean: Removes files generated by the previous build.
- post-clean: Executes processes after cleaning.
The Site Lifecycle is responsible for generating and deploying project documentation. Phases in the Site Lifecycle:
- pre-site: Executes processes before generating site documentation.
- site: Generates the site documentation.
- post-site: Executes processes after generating site documentation.
- site-deploy: Deploys the generated site documentation to a web server.
Maven Project Structure
project-root
โโโ mvnw # Maven wrapper, allows you to run a Maven project without installing Maven separately
โ # Preferred way over mvn
โโโ mvnw.cmd
โโโ pom.xml # Maven config file
โโโ src
โ โโโ main
โ โ โโโ java # Java source code
โ โ โ โโโ com
โ โ โ โโโ example
โ โ โ โโโ MyApp.java
โ โ โโโ resources # Non-Java resources (properties and configs used by your app)
โ โ โโโ webapp # Web application resources (JSP files, web configs, assets, etc.)
โ โ # Only work with WAR packaging, not with JAR
โ โโโ test
โ โโโ java # Test source code
โ โโโ com
โ โโโ example
โ โโโ MyAppTest.java
โ
โโโ target # Destination directory for compiled codepom.xml
<!-- Project metadata and configs -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- Project coordinates -->
<groupId>com.app</groupId>
<artifactId>mavencommends</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mavencommends</name>
<description>Spring Reactive</description>
<properties>
<java.version>17</java.version>
</properties>
<!-- Dependencies are Maven artifacts/components required for the project -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- Plugins perform tasks for a Maven build. These are not packaged in the application -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!-- Create separate build configurations for different environments like development, testing, and production -->
<profiles>
<profile>
<id>dev</id>
<properties>
<environment>development</environment>
<debug>true</debug>
</properties>
</profile>
</profiles>
<!-- Specifies plugins used to generate reports like Javadoc or test coverage -->
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.9.1</version>
</plugin>
</plugins>
</reporting>
</project>Essential Maven Command
General maven command syntax: mvn [options] [goal(s)] [phase(s)].
| Command | What it does | When to use it | Notes |
|---|---|---|---|
mvn -v | Shows Maven version, Java version, Java home, and OS info. | When checking your local environment or debugging build issues. | Useful after switching JDK versions. |
mvn clean | Deletes generated build files, usually the target/ directory. | When old compiled files or stale build artifacts cause issues. | Commonly combined with another phase. |
mvn compile | Compiles main source code under src/main/java. | When you only want to check whether production code compiles. | Does not run tests or create a JAR. |
mvn test | Runs unit tests. | During development or before committing code. | Usually runs tests under src/test/java. |
mvn -Dtest=UserServiceTest test | Runs one test class. | When debugging or repeatedly running one test class. | Replace UserServiceTest with your test class name. -Dxxx=yyy sets a Maven property. |
mvn -Dtest=UserServiceTest#shouldCreateUser test | Runs one specific test method. | When fixing one failing test method. | Format: ClassName#methodName. |
mvn package | Compiles, tests, and packages the project into a JAR/WAR. | When you need a build artifact. | Output usually appears in target/. |
mvn clean package | Cleans old build files, then creates a fresh package. | Before local deployment or checking a clean build. | Very common command in real projects. |
mvn package -DskipTests | Packages the project without running tests. | When you need a quick local build. | Test code may still be compiled. |
mvn package -Dmaven.test.skip=true | Skips compiling and running tests. | Rarely, when test code itself is broken or unavailable. | Stronger than -DskipTests; use carefully. |
mvn verify | Runs all lifecycle checks up to the verify phase. | Before pushing code or opening a pull request. | May include integration tests, static analysis, style checks, etc. |
mvn clean verify | Runs a clean full verification. | Best local command before pushing code. | Stronger than mvn test. |
mvn install | Builds the project and installs the artifact into local .m2. | When another local project depends on this project. | Useful for multi-project local development. |
mvn clean install | Cleans, builds, tests, packages, and installs locally. | When publishing a local dependency for another project. | Common in library/module development. |
mvn deploy | Builds and uploads artifact to a remote Maven repository. | In CI/CD or release pipelines. | Usually not used manually in daily development. |
mvn wrapper:wrapper | Adds Maven Wrapper files to the project. | When setting up a project for team/CI consistency. | Creates files like mvnw, mvnw.cmd, and .mvn/. |
mvn spring-boot:run | Starts a Spring Boot application. | During local Spring Boot development. | Runs the app without manually packaging a JAR. |
mvn spring-boot:run -Dspring-boot.run.profiles=dev | Starts Spring Boot with the dev profile. | When using application-dev.yml or application-dev.properties. | Maven profile and Spring profile are different concepts. |
mvn spring-boot:run -Dspring-boot.run.arguments=--spring.profiles.active=dev | Starts Spring Boot and passes runtime arguments. | When you want to pass Spring Boot command-line options. | More flexible than spring-boot.run.profiles. |
mvn spring-boot:run -Dspring-boot.run.arguments=--server.port=9090 | Starts Spring Boot on port 9090. | When default port 8080 is already used. | Useful when running multiple services locally. |
mvn clean package && java -jar target/app.jar | Builds and runs the packaged JAR. | When testing the final runnable artifact. | Replace app.jar with the real generated JAR name. |
java -jar target/app.jar --spring.profiles.active=dev | Runs packaged Spring Boot JAR with the dev profile. | When testing runtime behavior after packaging. | This is not a Maven command, but commonly used with Maven builds. |
mvn package spring-boot:repackage | Repackages a normal JAR/WAR into an executable Spring Boot archive. | When Spring Boot repackage is not automatically bound to package. | Often unnecessary if plugin is configured normally. |
mvn spring-boot:build-image | Builds a container image for a Spring Boot app. | When containerizing a Spring Boot service. | Uses buildpacks; no Dockerfile needed in many cases. |
mvn spring-boot:build-image -Dspring-boot.build-image.imageName=my-app:latest | Builds a Spring Boot container image with a custom name. | When preparing a local or deployable image. | Replace my-app:latest with your image name/tag. |
mvn clean package -Pdev | Builds with Maven profile dev. | When pom.xml defines environment-specific build profiles. | -Pdev is a Maven profile, not a Spring profile. |
mvn clean package -Pdev,local | Activates multiple Maven profiles. | When combining build configurations. | Profiles are comma-separated. |
mvn test -Denv=local | Passes a system/build property into Maven. | When tests or plugins read custom properties. | -Dkey=value is widely used in Maven. |
mvn clean package -Drevision=1.2.3 | Builds with a custom version/property value. | In release or CI pipelines. | Only works if the POM uses that property. |
mvn clean package -U | Forces Maven to update snapshots and check remote dependencies. | When Maven seems stuck on an old dependency version. | Useful for SNAPSHOT dependency issues. |
mvn package -o | Runs Maven in offline mode. | When working without internet. | Dependencies must already exist in local .m2. |
mvn dependency:go-offline | Downloads dependencies and plugins for offline use. | Before travel, Docker builds, or CI caching. | Helps prepare offline builds. |
mvn dependency:tree | Shows the dependency tree. | When debugging dependency conflicts. | Very useful for NoSuchMethodError or version mismatch issues. |
mvn dependency:tree -Dincludes=org.springframework | Shows dependency tree filtered by group/artifact. | When investigating a specific dependency family. | Replace org.springframework with your target dependency. |
mvn dependency:analyze | Finds unused or undeclared dependencies. | When cleaning up pom.xml. | Not always perfect, but helpful. |
mvn dependency:resolve | Resolves and downloads project dependencies. | When preparing cache or troubleshooting dependencies. | Does not necessarily build the project. |
mvn dependency:purge-local-repository | Removes project dependencies from local .m2 and re-resolves them. | When local Maven cache may be corrupted. | Useful for broken downloaded artifacts. |
mvn -f backend/pom.xml clean package | Runs Maven using a specific POM file. | In monorepos or scripts. | -f points to a POM file or project directory. |
mvn -pl user-service clean package | Builds only the selected module. | In multi-module projects when only one module changed. | -pl means project list. |
mvn -pl user-service -am clean package | Builds selected module and required dependent modules. | When the module depends on other local modules. | -am means also make dependencies. |
mvn -rf payment-service clean install | Resumes a failed multi-module build from a module. | In large projects after fixing a failed module. | -rf means resume from. |
mvn clean package -X | Runs Maven with debug logs. | When build behavior is unclear. | Very verbose. |
mvn test -e | Shows full error stack traces. | When you need more error details but not full debug logs. | Less noisy than -X. |
mvn clean verify -B -ntp | Runs a CI-friendly build with less console noise. | In GitHub Actions, GitLab CI, Jenkins, etc. | -B = batch mode, -ntp = no transfer progress. |
mvn clean install -T 4 | Builds using 4 threads. | In large multi-module projects. | Can speed up builds. |
mvn clean install -T 1C | Builds using 1 thread per CPU core. | In larger projects or CI. | Good for parallel Maven builds. |
mvn help:effective-pom | Shows the final POM after inheritance, plugins, and profiles are applied. | When debugging Maven configuration. | Useful when parent POMs or profiles make behavior confusing. |
mvn help:effective-settings | Shows the effective Maven settings. | When debugging repository, proxy, mirror, or credential issues. | Helps inspect settings.xml behavior. |
