Table of Contents
URL: https://www.progressiverobot.com/install-maven-linux-ubuntu/
Apache Maven is a cornerstone tool for building and managing Java projects, trusted by developers worldwide. This guide will walk you through installing the latest version of Maven on Ubuntu, ensuring your development environment is robust, up-to-date, and ready for any Java project—whether you’re just starting out or managing complex enterprise builds. Let’s get your system set up for seamless Java development with Maven.
Introduction
This guide provides step-by-step instructions for installing Apache Maven 3.9.9 on Ubuntu with JDK 17, covering multiple installation methods, configuration, troubleshooting, and frequently asked questions.
Key Takeaways
Java Development Kit (JDK) 17 is a Long-Term Support (LTS) release, meaning it receives updates and security patches for several years, making it a reliable foundation for enterprise and production environments. Using JDK 17 ensures compatibility with the latest Maven features and plugins, and it is widely supported by the Java ecosystem, reducing the risk of encountering deprecated or unsupported APIs.
- JDK 17 (LTS) is the recommended Java version for Maven installations due to long-term support and stability.
Apache Maven 3.9.9 introduces important bug fixes, performance improvements, and enhanced compatibility with modern Java versions. Staying up to date with the latest Maven release ensures access to new features, improved dependency resolution, and better integration with CI/CD tools. It also helps avoid issues caused by outdated plugins or incompatibilities with recent Java releases.
- Apache Maven 3.9.9 is the latest stable version at the time of writing.
You can install Maven on Ubuntu using several approaches: the apt package manager for convenience, downloading official binaries for full control, SDKMAN for easy version management and switching, or automation scripts for reproducible, idempotent setups in CI/CD pipelines. Each method has trade-offs in terms of version freshness, ease of updates, and suitability for automation or production use.
- Multiple installation methods are available: apt, binaries, SDKMAN, and automation scripts.
Correctly configuring environment variables such as JAVA_HOME (pointing to your JDK installation) and M2_HOME (pointing to your Maven directory) is crucial for Maven and Java tools to function as expected. Adding these variables to your shell profile and ensuring they are included in your PATH allows both Maven and Java commands to be recognized system-wide, preventing common errors during builds.
- Setting environment variables like
JAVA_HOMEandM2_HOMEis essential for proper configuration.
After installation, running java -version and mvn -version in your terminal confirms that both Java and Maven are properly set up and accessible from your environment. These commands display the installed versions and their paths, helping you quickly identify misconfigurations or version mismatches before starting development or automation tasks.
- Verification commands ensure both JDK and Maven are installed correctly.
Creating and building a sample Maven project is a practical way to verify that your Maven setup works end-to-end. By generating a new project with mvn archetype:generate and running a build, you can ensure that dependencies are resolved, plugins function correctly, and your environment is ready for real-world Java development. This step also familiarizes you with Maven’s workflow and project structure.
- Sample Maven project creation helps validate the installation.
What is Apache Maven?
Apache Maven is a powerful build automation and project management tool primarily used for Java projects. It simplifies the build process, dependency management, and project documentation through a standardized project structure and configuration using XML files (pom.xml).
Who Should Use Maven?
Maven is an essential tool for developers at all skill levels. For beginners, it simplifies the complex process of building Java applications by managing dependencies and providing a standardized project structure. Intermediate developers benefit from its robust lifecycle management and easy integration with continuous integration/continuous deployment (CI/CD) pipelines, which streamline development workflows. Advanced developers appreciate Maven’s extensibility and support for complex multi-module projects, making it an indispensable tool for scalable and maintainable software development.
By automating builds and managing dependencies, Maven reduces manual errors and ensures consistent project setups across teams. Its strong integration with popular CI/CD tools helps teams deploy applications reliably and efficiently, making it a valuable asset in modern software development environments.
Prerequisites
Before installing Maven, ensure you have:
- A Linux system (preferably Ubuntu for this tutorial)
- Basic command line knowledge.
- Internet connectivity to download packages and binaries
- Administrative privileges (
sudoaccess) for installation steps - Java Development Kit installed (preferably JDK 17). If you need help, check out our How To Install Java on Ubuntu guide.
Install Java (OpenJDK 17 on Ubuntu)
JDK 17 is the recommended Java version for Maven. You can install it via Ubuntu's package manager or, optionally, from an official tarball for finer control.
Install via APT (Recommended)
Install OpenJDK 17 using Ubuntu's package manager for simplicity and security updates:
sudo apt update
sudo apt install openjdk-17-jdk
Set JAVA_HOME and add it to your PATH (add these lines to your ~/.profile or ~/.bashrc):
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export PATH="$JAVA_HOME/bin:$PATH"
Apply the changes:
source ~/.profile
Verify the installation:
java -version
Expected output:
openjdk version "17.0.x"
OpenJDK Runtime Environment (build 17.0.x+...)
OpenJDK 64-Bit Server VM (build 17.0.x+..., mixed mode, sharing)
Optional: Install from Tarball (Temurin)
For maximum control or to use the Adoptium Temurin distribution, download and install the tarball:
wget https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.10+7/OpenJDK17U-jdk_x64_linux_hotspot_17.0.10_7.tar.gz
tar -xvf OpenJDK17U-jdk_x64_linux_hotspot_17.0.10_7.tar.gz
sudo mv jdk-17.0.10+7 /opt/jdk-17
Set JAVA_HOME and update your PATH (add to ~/.profile or ~/.bashrc):
export JAVA_HOME=/opt/jdk-17
export PATH="$JAVA_HOME/bin:$PATH"
Apply the changes:
source ~/.profile
Verify:
java -version
Install Maven on Ubuntu
There are several ways to install Maven. Choose the method that best fits your requirements.
Install via APT
You can install Maven using Ubuntu's package manager. Note: The version may be outdated compared to upstream releases.
sudo apt update
sudo apt install maven
> Tip: Use -y with apt install for unattended, non-interactive upgrades or automation contexts.
Verify the installed version:
mvn -version
If you require the latest Maven version, consider the binary or SDKMAN installation methods below.
Example usage after APT installation:
mvn compile
mvn package
The mvn compile command compiles your project's source code, turning it into executable bytecode. The mvn package command then takes the compiled code and bundles it into a distributable format, such as a JAR or WAR file.
Install from Binary (3.9.9)
Download the official Apache Maven 3.9.9 binary archive, extract it, and configure environment variables.
wget https://dlcdn.apache.org/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.tar.gz
tar -xvf apache-maven-3.9.9-bin.tar.gz
sudo mv apache-maven-3.9.9 /opt/
# Verify checksum
wget https://downloads.apache.org/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.tar.gz.sha512
sha512sum -c apache-maven-3.9.9-bin.tar.gz.sha512
# Optional: verify signature with KEYS
wget https://downloads.apache.org/maven/KEYS
gpg --import KEYS
gpg --verify apache-maven-3.9.9-bin.tar.gz.asc apache-maven-3.9.9-bin.tar.gz
Set M2_HOME and update your PATH (add to ~/.profile or ~/.bashrc):
export M2_HOME=/opt/apache-maven-3.9.9
export PATH="$M2_HOME/bin:$PATH"
Apply the changes:
source ~/.profile
Verify:
mvn -version
Expected output:
Apache Maven 3.9.9 (9f3a6d9b4e9a6e0a5e9b7a3f6e1b5f1d3c1a7b2c)
Maven home: /opt/apache-maven-3.9.9
Java version: 17, vendor: Eclipse Adoptium, runtime: /usr/lib/jvm/java-17-openjdk-amd64
Default locale: en, platform encoding: UTF-8
OS name: "linux", version: "5.15.0-58-generic", arch: "amd64", family: "unix"
> Note: Depending on whether you installed OpenJDK via APT or Temurin via tarball, the Java runtime path may show /usr/lib/jvm/java-17-openjdk-amd64 or /opt/jdk-17.
Install via SDKMAN (3.9.9)
SDKMAN is a tool for managing parallel versions of multiple Software Development Kits, including Java and Maven.
Install SDKMAN:
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
Install Maven 3.9.9:
sdk install maven 3.9.9
Verify:
mvn -version
Managing Maven versions with SDKMAN:
sdk use maven 3.9.9
sdk list maven
sdk use maven <version> allows you to switch between Maven versions on the fly. sdk list maven shows all available Maven versions.
Use the Maven Wrapper
The Maven Wrapper (mvnw) is a script that allows you to run a Maven project with a specific Maven version without requiring Maven to be installed globally on your system. This ensures consistent builds across different environments and team members.
Usage example:
./mvnw clean install
Running ./mvnw clean install will download the required Maven version automatically if not present and execute the build lifecycle phases. This approach reduces setup complexity and avoids version conflicts in team environments.
> Note: Maven Wrapper is often preferred in teams to guarantee build consistency and ease onboarding.
Configure Environment Variables
Properly setting environment variables ensures that Java and Maven work as expected.
Add the following lines to your ~/.profile or ~/.bashrc (adjust the paths as needed for your installation method):
For APT-based OpenJDK 17:
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
For tarball-based OpenJDK (Temurin):
export JAVA_HOME=/opt/jdk-17
For Maven (binary install):
export M2_HOME=/opt/apache-maven-3.9.9
Add both to your PATH:
export PATH="$JAVA_HOME/bin:$M2_HOME/bin:$PATH"
# System-wide (all users)
sudo tee /etc/profile.d/maven.sh >/dev/null <<'EOF'
export M2_HOME=/opt/apache-maven-3.9.9
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export PATH="$JAVA_HOME/bin:$M2_HOME/bin:$PATH"
EOF
sudo chmod +x /etc/profile.d/maven.sh
Apply the changes:
source ~/.profile
Verify:
echo $JAVA_HOME
echo $M2_HOME
which mvn
Verify Installation
To confirm Maven and Java are installed correctly:
mvn -version
java -version
You should see Maven version, Java version, and environment details confirming successful installation.
Implementation Example (Hello World)
How to create and run a simple Maven project:
- Create a new directory and navigate into it:
mkdir maven-hello-world
cd maven-hello-world
- Generate a Maven project using the archetype plugin:
mvn archetype:generate -DgroupId=com.example -DartifactId=hello-world -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
- Navigate to the project directory:
cd hello-world
- Compile the project:
mvn compile
Or package it as a JAR:
mvn package
- Run the Java application:
java -cp target/hello-world-1.0-SNAPSHOT.jar com.example.App
Expected output:
Hello World!
This confirms your Maven installation is working correctly.
Decision Guide (APT vs Binary vs SDKMAN vs Automation)
| Method | Version Freshness | Upgrade Path | Idempotent? | Corporate Policy Friendly? | Offline Install Support | Pros | Cons | Recommended For |
|---|---|---|---|---|---|---|---|---|
| apt | Low (often outdated) | Manual (via apt upgrade) | Yes | High (uses system package manager) | Medium (with apt cache) | Simple, native integration, minimal setup | May not have latest Maven/Java versions | Beginners or quick system-native installs |
| Binaries | High (latest release) | Manual (replace tarball and symlink) | Yes | Medium (manual paths) | High | Full control, version pinning, portable | Requires manual setup and env var configuration | Developers who want control and latest features |
| SDKMAN | Very High (multi-version) | Automated (sdk upgrade/use) | Yes | Medium (user-level tool) | Low | Easiest multi-version management, rapid switching | Requires extra tool, may not comply with corp policy | Devs managing multiple Java/Maven versions or testing |
| Automation (Ansible/Bash) | Configurable | Scripted upgrade logic | Yes | High (auditable, repeatable) | High | Infrastructure-as-code, CI/CD ready, repeatable installs | Requires scripting knowledge and maintenance | Teams, DevOps, repeatable infra setup |
> Note: APT and Snap may have larger footprints due to packaging overhead. In air-gapped or disk-constrained environments, binaries or automation scripts are often preferred.
Choose the method that best fits your needs based on your expertise and environment requirements.
Troubleshooting
- Ensure environment variables
JAVA_HOMEandM2_HOMEare correctly set. - Confirm that
$JAVA_HOME/binand$M2_HOME/binare in yourPATH. - Run
source ~/.profileor restart your terminal after changes.
If multiple Java versions are installed, you can select the active version:
sudo update-alternatives --config java
Follow the prompts to select the desired Java version. Then ensure JAVA_HOME matches the selected version.
- Check your internet connection.
- Verify your
settings.xmlin~/.m2for repository configurations. - Clear your local repository cache by deleting
~/.m2/repository.
Edit your ~/.m2/settings.xml to add proxies and mirrors if needed:
<settings>
<proxies>
<proxy>
<id>example-proxy</id>
<active>true</active>
<protocol>http</protocol>
<host>proxy.example.com</host>
<port>8080</port>
</proxy>
</proxies>
<mirrors>
<mirror>
<id>central-mirror</id>
<mirrorOf>central</mirrorOf>
<url>https://your-mirror/repo</url>
</mirror>
</mirrors>
</settings> - Make sure
JAVA_HOMEpoints to the correct JDK 17 directory. - Run
java -versionandmvn -versionto confirm versions.
Advanced Usage and Optimization
Using Maven in CI/CD Pipelines with Docker
Here’s an example Dockerfile snippet to install Maven in a CI/CD environment:
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y openjdk-17-jdk maven
WORKDIR /app
COPY . .
RUN mvn clean install
> Tip: Add -y to apt-get install (as shown) for non-interactive installs in CI/CD pipelines.
This setup allows you to build your Java projects inside a container, ensuring a consistent environment across all stages of your CI/CD pipeline.
> Note: Containerizing builds improves reproducibility and isolates dependencies from the host system.
Performance Optimization Tips
mvn -T 1C clean install
Using the -T 1C flag enables parallel builds utilizing one thread per CPU core, significantly speeding up compilation and packaging. Additionally, configuring mirrors in your settings.xml can improve dependency download speeds by using geographically closer repositories.
> Note: Parallel builds and mirrors reduce build times and improve developer productivity, especially in large projects.
CI/CD Integration Note
Integrating Maven into CI/CD pipelines automates testing, building, and deployment processes, minimizing manual intervention and errors. Tools like Jenkins, GitHub Actions, and GitLab CI can invoke Maven commands to ensure code quality and consistent releases.
Parallel Build Optimization Note
Leveraging Maven’s parallel build capabilities (-T) helps utilize system resources efficiently, reducing build times. However, not all Maven plugins support parallel execution, so testing is essential before enabling it in production pipelines.
Infrastructure as Code: Ansible Playbook (Ubuntu)
Use this ready-to-run Ansible playbook to install OpenJDK 17+ and Apache Maven from the official Ubuntu repositories. It is idempotent (safe to re-run), contains explanatory comments, and triggers a handler to verify mvn -version at the end. This is designed for team-scale, repeatable installs.
- name: Install Java 17+ and Apache Maven on Ubuntu
hosts: maven_hosts # Define your inventory group
become: true # Elevate privileges for package installs
gather_facts: true
vars:
java_package: openjdk-17-jdk
pre_tasks:
# Ensure apt metadata is fresh; prevents 404 errors and pulls security updates
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
tasks:
# 1) Ensure a compatible JDK (>= 17) exists. This will not downgrade newer JDKs.
- name: Ensure OpenJDK 17+ is installed (idempotent)
ansible.builtin.apt:
name: "{{ java_package }}"
state: present
# 2) Install Maven from Ubuntu repositories for stability and OS integration
- name: Ensure Apache Maven is installed from Ubuntu repo (idempotent)
ansible.builtin.apt:
name: maven
state: present
notify: Verify Maven installation
# 3) Optionally verify mvn is discoverable on PATH for non-login shells
- name: Check Maven is on PATH
ansible.builtin.command: bash -lc 'command -v mvn'
register: mvn_path
changed_when: false
# 4) Flush handlers so verification runs within the same play
- name: Flush handlers to verify installation now
ansible.builtin.meta: flush_handlers
handlers:
# Handler runs only when Maven installation task reports a change.
- name: Verify Maven installation
listen: Verify Maven installation
ansible.builtin.command: mvn -version
register: mvn_version
changed_when: false
failed_when: mvn_version.rc != 0
- name: Output Maven version
listen: Verify Maven installation
ansible.builtin.debug:
msg: "{{ mvn_version.stdout | default(mvn_version.stderr) }}"
AI-Powered Maven Workflows and Use Cases (In-Depth)
Installing Maven is table stakes. The real leverage comes from pairing Maven with AI to automate configuration, speed up CI/CD, harden security, and reduce mean time to green. The patterns below are implementation-grade: prompt ideas, exact commands, and “why it matters” so readers can copy-paste with confidence and understand the tradeoffs.
- AI-Generated pom.xml with Guardrails (Reproducible, Policy-Aware)
Answer: Use an LLM to draft/refactor pom.xml that enforces org policy (Java toolchain, reproducible builds, plugin baselines), then validate with Enforcer. How:
Prompt an LLM to create pom.xml with:
pluginManagement (surefire, failsafe, compiler with release 17/21),
Maven Enforcer rules (min Java, banned deps),
Reproducible builds (deterministic jars, timestamps).
Validate locally:
mvn -q -DskipTests dependency:resolve enforcer:enforce
mvn -q help:effective-pom > effective-pom.xml
Feed any Enforcer failures back to the LLM for a revised pom.xml. Why it matters: You codify standards on day one, avoid drift, and ship a stable baseline that scales across teams.
- AI-Assisted Dependency Conflict Resolution (Stop “Tree-Gazing”)
Answer: Generate a dependency tree, let AI propose the minimal dependencyManagement pin set, then re-verify. How:
mvn -q dependency:tree -Dscope=compile > deps.txt
mvn -q versions:use-latest-releases -DgenerateBackupPoms=false -DdryRun > versions.txt
Ask an LLM:
From deps.txt + versions.txt, propose a minimal dependencyManagement block to resolve conflicts and justify each version.
Apply the suggested block, then:
mvn -q -DskipTests dependency:resolve
Why it matters: Faster conflict triage, fewer risky upgrades, clearer justifications for code review.
- LLM-Generated CI/CD for Maven (Matrix, Cache, Test Reports, Signing)
Answer: Have an LLM author a best-practice pipeline with JDK matrix, Maven cache, test reports, and optional signing/publish. GitHub Actions example:
name: Maven Build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
java: [17, 21]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: ${{ matrix.java }}
cache: maven
- name: Build & Test
run: mvn -B -U clean verify
- name: Upload Test Reports
if: always()
uses: actions/upload-artifact@v4
with:
name: surefire-reports
path: '**/target/surefire-reports/*.xml'
Why it matters: Consistency across environments, faster builds, and visibility into failures.
- AI-Powered Install Automation (Idempotent Bash, cloud-init, Ansible)
Answer: Ask an LLM for an idempotent installer that detects Ubuntu version, ensures JDK, installs Maven, exports env vars, and self-verifies. Bash skeleton (idempotent):
#!/usr/bin/env bash
set -euo pipefail
if ! command -v mvn >/dev/null 2>&1; then
sudo apt-get update -y
sudo apt-get install -y openjdk-21-jdk maven
fi
mvn -version
cloud-init (for droplets/VMs):
#cloud-config
packages: [openjdk-21-jdk, maven]
runcmd: [ "mvn -version" ]
Why it matters: Repeatable, auditable installs that plug into CI, golden images, and autoscaling workflows.
- Security: OWASP + SBOM + AI Triage (Real-World Risk Reduction)
Answer: Generate a vulnerability report and SBOM; have AI prioritize fixes by exploitability/impact and propose safe ranges. How:
# OWASP Dependency-Check
mvn org.owasp:dependency-check-maven:check -Dformat=JSON -Doutput=dc.json
# CycloneDX SBOM
mvn org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom -Dcyclonedx.output.format=json
> Tip: Use -B (batch mode) with Maven in automation scripts to ensure non-interactive builds: mvn -B clean install.
Prompt:
From dc.json + SBOM, group CVEs by severity and known exploits, propose minimal upgrades, note breaking changes.
Why it matters: Converts raw scanner noise into actionable upgrades and review-ready PR notes.
- Log-Driven Troubleshooting with AI (Surefire/Enforcer/JAVA_HOME)
Answer: Pipe failing logs to an LLM to classify root cause (config, env, flaky test) and return exact patch steps. How:
mvn -B clean verify 2> build.log || true
Prompt:
Classify root cause from build.log + surefire-reports, propose minimal diffs and env fixes.
Why it matters: Cuts mean time to green; better than generic “try -X” advice since it returns precise diffs and env fixes.
- Release Notes & Versioning, Auto-Drafted by AI (Conventional Commits)
Answer: Use Conventional Commits and have AI draft human-grade release notes from commit history and test reports. How:
After mvn verify, collect commits since last tag; ask the LLM for a CHANGELOG with breaking changes, features, fixes, PR links, Java compatibility notes.
Publish as CHANGELOG.md and GitHub Release body. Why it matters: Clean release hygiene, less PM time, better consumer transparency.
AI Workflows: Install & Automate Maven
Example LLM Prompt: Generate an Idempotent Maven Install Script (Ubuntu)
You are a senior DevOps engineer. Write an idempotent bash script for Ubuntu 22.04/24.04 that:
- Ensures OpenJDK 17+ and Maven are installed using apt if not present
- Exports JAVA_HOME and ensures mvn is on PATH for login shells
- Is safe to re-run and exits on errors
- Prints `java -version` and `mvn -version` for validation at the end
Constraints:
- Non-interactive; suitable for CI
- Use set -euo pipefail
- Detect existing installs without reinstalling
Output only a single bash script in a code block.
Annotated Output Script + Validation
#!/usr/bin/env bash
set -euo pipefail
# Detect distro (Ubuntu) and refresh apt metadata once
if ! command -v lsb_release >/dev/null 2>&1; then sudo apt-get update -y; fi
sudo apt-get update -y
# Ensure JDK 17+ is present (idempotent)
if ! command -v java >/dev/null 2>&1; then
sudo apt-get install -y openjdk-17-jdk
fi
# Ensure Maven is present (idempotent)
if ! command -v mvn >/dev/null 2>&1; then
sudo apt-get install -y maven
fi
# Export JAVA_HOME for current shell and future logins (user-scoped)
JAVA_BIN_PATH="$(readlink -f "$(command -v java)")"
JAVA_HOME_CANDIDATE="${JAVA_BIN_PATH%/bin/java}"
if [ -d "$JAVA_HOME_CANDIDATE" ]; then
export JAVA_HOME="$JAVA_HOME_CANDIDATE"
fi
PROFILE_FILE="$HOME/.profile"
if ! grep -q "JAVA_HOME" "$PROFILE_FILE" 2>/dev/null; then
{
echo "export JAVA_HOME=$JAVA_HOME"
echo 'export PATH="$JAVA_HOME/bin:$PATH"'
} >> "$PROFILE_FILE"
fi
# Quick validation
java -version
mvn -version
Validation steps:
- Run the script and ensure both commands return expected versions:
java -versionshould show 17+.mvn -versionshould show Maven with the Java runtime path.- Open a new shell and re-run
mvn -versionto confirmPATH/JAVA_HOMEpersistence.
Terraform, Ansible, and cloud-init Snippets
Terraform (cloud servers with cloud-init)
provider "the cloud provider" {}
resource "the cloud provider_droplet" "maven_host" {
name = "maven-ubuntu"
region = "nyc3"
size = "s-1vcpu-1gb"
image = "ubuntu-24-04-x64"
ssh_keys = [var.ssh_key_fingerprint]
user_data = file("cloud-init-maven.yaml")
backups = false
monitoring = true
ipv6 = true
}
cloud-init (Installs OpenJDK 17+ and Maven, validates)
#cloud-config
package_update: true
packages:
- openjdk-17-jdk
- maven
runcmd:
- [ bash, -lc, "java -version" ]
- [ bash, -lc, "mvn -version" ]
Ansible (Minimal, idempotent)
- name: Ensure Java 17+ and Maven on Ubuntu
hosts: all
become: true
tasks:
- name: Install OpenJDK 17+
ansible.builtin.apt:
name: openjdk-17-jdk
state: present
update_cache: true
- name: Install Maven
ansible.builtin.apt:
name: maven
state: present
- name: Validate Java and Maven
ansible.builtin.shell: |
set -euo pipefail
java -version
mvn -version
args:
executable: /bin/bash
register: validate_out
changed_when: false
Frequently Asked Questions
While apt is convenient, Ubuntu repositories often provide outdated Maven versions, which may lack critical features or compatibility with newer Java releases. For production, CI/CD, or when you need to pin or upgrade Maven versions reliably, prefer SDKMAN or manual binary installation. SDKMAN is scriptable and supports version switching, making it ideal for automation and reproducibility.
Pro Tip: Always verify the installed Maven version with mvn -version in your automation scripts to avoid unexpected mismatches.
Maven relies on the JAVA_HOME environment variable to locate the JDK. If multiple JDKs are present, explicitly set JAVA_HOME in your shell profile, CI/CD pipeline, or Dockerfile. For multi-user or multi-project systems, tools like jEnv or SDKMAN can help manage and switch Java versions per shell or project.
- SDKMAN: Use
sdk install maven <version>orsdk use maven <version>to switch versions per shell or script. - Manual: Download the desired Maven binary, update
M2_HOMEand yourPATH, and remove or archive the old version. - Automated Environments: Pin the Maven version in your Dockerfile, Ansible playbook, or CI/CD config for reproducibility.
Edge Case: If you have system-wide and user-specific Maven installations, ensure your PATH prioritizes the intended version.
JAVA_HOME: Required for Maven to find the Java compiler and runtime. Set it explicitly to avoid picking up the wrong Java version.M2_HOME: Points to your Maven installation directory. Not always required, but recommended for clarity, especially with multiple Maven versions.PATH: Ensure both$JAVA_HOME/binand$M2_HOME/binare in yourPATH.
For system-wide settings, add these to /etc/profile.d/ scripts. For user-specific or CI/CD, set them in .bashrc, .profile, or your pipeline config.
Use configuration management tools like Ansible, Chef, or Puppet to script installation and environment variable setup. For containers, define installation steps in your Dockerfile. SDKMAN supports non-interactive installation (sdk install maven <version> -y), making it suitable for automation.
Edit your ~/.m2/settings.xml (or global /etc/maven/settings.xml) to:
- Define
<mirrors>for faster or internal artifact resolution. - Set up
<proxies>for environments behind corporate firewalls. - Add
<servers>for authentication to private repositories (e.g., Nexus, Artifactory).
For reproducible builds, version-control a custom settings.xml and reference it with mvn -s <path> in your CI/CD scripts.
- Use parallel builds:
mvn -T 1C clean install(one thread per CPU core). - Enable build caching with Maven Build Cache Extension.
- Configure dependency mirrors close to your build agents.
- Use the
--fail-fastor--fail-at-endflags for better error handling in multi-module projects.
- Run with
-Xfor full debug output:mvn -X clean install. - Check for environment variable mismatches (
JAVA_HOME,M2_HOME,PATH). - Inspect
settings.xmlfor misconfigured repositories or proxies. - Clear the local repository cache:
rm -rf ~/.m2/repository. - Compare
java -versionandmvn -versionoutputs to ensure alignment.
- If installed via APT:
sudo apt remove maven
Optionally, remove configuration and cache:
rm -rf ~/.m2
- If installed from a tarball or binary:
sudo rm -rf /opt/apache-maven-3.9.9
Remove any related environment variable lines from your ~/.profile or ~/.bashrc.
- To find the location of the
mvnbinary:
which mvn
- To list all files installed by the APT package:
dpkg -L maven
- To see the actual path of the Maven binary:
readlink -f $(which mvn) Conclusion
You have successfully installed Apache Maven on your Linux (Ubuntu) system using your preferred method. Maven is now ready to build and manage your Java projects efficiently. For advanced usage and automation, consider integrating Maven into your CI/CD pipelines. To learn more about deploying your Maven-based applications, explore How To Deploy to an app platform. Happy coding!