How to Install Apache Maven on Ubuntu 26.04 LTS (Step-by-Step Guide)

how to install apache maven on ubuntu 26.04 lts step by step

Table of Contents

  1. What is Apache Maven and Why Java Developers Need It
  2. APT Method vs Manual Install: Which One to Choose
  3. Prerequisites
  4. Method 1: Install Maven via APT (Simple)
  5. Method 2: Install Maven Manually from Apache (Recommended)
  6. Step: Configure Environment Variables
  7. Verify the Installation
  8. Create and Build Your First Maven Project
  9. Understanding the Maven Build Lifecycle
  10. Configuring Maven: settings.xml
  11. Using Maven with Apache Tomcat for WAR Deployment
  12. Maven in CI/CD with GitHub Actions
  13. Maven vs Gradle: Which Build Tool to Choose
  14. Common Issues and Quick Fixes
  15. Next Steps

Every Java project eventually faces the same set of problems: where do dependencies come from, how does the code get compiled into a runnable artifact, how are tests executed consistently across different machines, and how does the output get packaged for deployment? Apache Maven solves all of these with a single, standardized approach — a pom.xml file that describes your project, and a build lifecycle that knows what to do with it.

This guide covers two installation methods for Maven 3.9.16 on Ubuntu 26.04 LTS — the quick APT method and the recommended manual install that gives you the latest upstream version — along with environment setup, your first project, and CI/CD integration.

What is Apache Maven and Why Java Developers Need It

Maven is a build automation and dependency management tool for Java projects (and other JVM languages). At its core, it does three things:

1. Dependency management — Instead of manually downloading JAR files and adding them to your classpath, you declare dependencies in pom.xml and Maven fetches them from Maven Central (or a private repository) automatically. Transitive dependencies (dependencies of your dependencies) are resolved the same way.

2. Standardized build lifecycle — Maven defines a fixed sequence of phases: validatecompiletestpackageverifyinstalldeploy. Every Maven project follows the same lifecycle, so any developer on the team (or any CI/CD system) knows exactly how to build it without reading setup docs.

3. Project structure convention — Maven enforces a standard directory layout (src/main/java, src/test/java, src/main/resources) that every Maven project shares. Tools, IDEs, and CI systems understand this layout without configuration.

The result: mvn clean package is all it takes to compile, test, and package a Maven project — regardless of how complex the project is.

APT Method vs Manual Install: Which One to Choose

APT MethodManual Install
Maven version on Ubuntu 26.043.9.12 (slightly behind upstream)3.9.16 (latest stable)
Setup time~2 minutes~5 minutes
System updatesManaged by apt upgradeManual update needed
Multiple versionsNoYes (via SDKMAN or manual symlinks)
Best forQuick dev setup, CI/CD containersProduction servers, teams needing specific versions

For most use cases on Ubuntu 26.04, the version difference between APT and manual is minor — both are on the Maven 3.9.x branch. Choose APT for simplicity, manual when you need the exact latest upstream version or want full control.

Prerequisites

  • Ubuntu 26.04 LTS (Resolute Raccoon)
  • Java 8 or higher installed (Java 21 recommended — see our Apache Tomcat guide for Java 21 setup steps)
  • sudo access
  • Internet connection

Verify Java is installed before proceeding:

java -version
# openjdk version "21.x.x" ...

echo $JAVA_HOME
# /usr/lib/jvm/java-21-openjdk-amd64

If Java is not installed:

sudo apt update
sudo apt install -y openjdk-21-jdk-headless

echo 'export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64' | \
  sudo tee /etc/profile.d/java.sh
source /etc/profile.d/java.sh

Method 1: Install Maven via APT (Simple)

The fastest way to get Maven running on Ubuntu 26.04:

sudo apt update
sudo apt install -y maven

Verify:

mvn -version

Expected output:

Apache Maven 3.9.12 (...)
Maven home: /usr/share/maven
Java version: 21.x.x, vendor: Ubuntu

That’s it for APT install — Maven is immediately available system-wide. Skip to the Verify the Installation section.

Method 2: Install Maven Manually from Apache (Recommended)

The manual method installs the latest upstream release (3.9.16 at time of writing) directly from Apache, giving you full control over the version:

Download Maven 3.9.16:

MAVEN_VERSION="3.9.16"

wget https://downloads.apache.org/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
  -O /tmp/maven.tar.gz

Verify the download checksum (recommended — protects against corrupted downloads):

wget https://downloads.apache.org/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz.sha512 \
  -O /tmp/maven.tar.gz.sha512

sha512sum -c /tmp/maven.tar.gz.sha512
# Expected: /tmp/maven.tar.gz: OK

Extract to /opt/maven:

sudo mkdir -p /opt/maven
sudo tar -xzf /tmp/maven.tar.gz -C /opt/maven --strip-components=1

# Verify
ls /opt/maven
# bin  boot  conf  lib  LICENSE  NOTICE  README.txt

Clean up:

rm /tmp/maven.tar.gz /tmp/maven.tar.gz.sha512

Step: Configure Environment Variables

Whether you used APT or manual install, setting JAVA_HOME, M2_HOME, and MAVEN_HOME in a profile script ensures they’re available for all users, login shells, and CI/CD processes:

sudo nano /etc/profile.d/maven.sh
# Apache Maven environment variables
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
export M2_HOME=/opt/maven
export MAVEN_HOME=/opt/maven
export PATH=${M2_HOME}/bin:${PATH}

Note for APT users: If you installed via APT, Maven is already on your PATH at /usr/bin/mvn. You still benefit from setting JAVA_HOME explicitly — Maven uses it to find the JDK when JAVA_HOME isn’t set, which can cause issues in non-interactive shells (like CI/CD runners).

Apply the changes:

sudo chmod +x /etc/profile.d/maven.sh
source /etc/profile.d/maven.sh

Verify the Installation

mvn -version

Expected output (manual install):

Apache Maven 3.9.16 (...)
Maven home: /opt/maven
Java version: 21.x.x, vendor: Ubuntu, runtime: /usr/lib/jvm/java-21-openjdk-amd64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "7.x.x-generic", arch: "amd64", family: "unix"

Confirm the correct Java is being used — the Java version line should match your intended JDK (21.x.x), not an older version that might be installed alongside it.

Create and Build Your First Maven Project

Maven’s archetype:generate command scaffolds a complete project structure:

mvn archetype:generate \
  -DgroupId=com.bckinfo \
  -DartifactId=my-first-app \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DarchetypeVersion=1.5 \
  -DinteractiveMode=false

This creates the following structure:

my-first-app/
├── pom.xml                          ← Project descriptor
└── src/
    ├── main/
    │   └── java/
    │       └── com/bckinfo/
    │           └── App.java         ← Main class
    └── test/
        └── java/
            └── com/bckinfo/
                └── AppTest.java     ← Unit test

Build the project:

cd my-first-app
mvn clean package

Maven executes the build lifecycle — downloads dependencies, compiles the source, runs tests, and packages everything into a JAR:

[INFO] --- maven-compiler-plugin:3.13.0:compile ---
[INFO] Compiling 1 source file with javac [debug release 8]
[INFO] --- maven-surefire-plugin:3.3.1:test ---
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- maven-jar-plugin:3.4.2:jar ---
[INFO] Building jar: target/my-first-app-1.0-SNAPSHOT.jar
[INFO] BUILD SUCCESS

Run the packaged JAR:

java -cp target/my-first-app-1.0-SNAPSHOT.jar com.bckinfo.App
# Hello World!

The pom.xml file — the heart of every Maven project:

<?xml version="1.0" encoding="UTF-8"?>
<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.bckinfo</groupId>
  <artifactId>my-first-app</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <properties>
    <maven.compiler.source>21</maven.compiler.source>
    <maven.compiler.target>21</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <!-- JUnit 5 for unit testing -->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>5.11.4</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.5.2</version>
      </plugin>
    </plugins>
  </build>
</project>

Understanding the Maven Build Lifecycle

Maven’s lifecycle phases run in order — each phase includes all previous phases:

PhaseWhat it does
mvn validateValidates project structure and POM
mvn compileCompiles source code to target/classes
mvn testRuns unit tests (doesn’t package)
mvn packagePackages compiled code into JAR/WAR
mvn verifyRuns integration tests on packaged artifact
mvn installInstalls artifact to local repository (~/.m2)
mvn deployCopies artifact to remote repository (Nexus, Artifactory)

Most frequently used commands:

# Clean build (removes target/ directory first — recommended for CI)
mvn clean package

# Skip tests (useful during development, not in CI)
mvn clean package -DskipTests

# Run only tests without packaging
mvn test

# Show dependency tree (debug classpath issues)
mvn dependency:tree

# Check for dependency updates
mvn versions:display-dependency-updates

# Parallel build (faster on multi-core machines — 1 thread per core)
mvn clean package -T 1C

Configuring Maven: settings.xml

Maven’s global configuration lives at /opt/maven/conf/settings.xml (system-wide) or ~/.m2/settings.xml (per-user). The most common things to configure:

Corporate proxy setup (if Maven needs to download dependencies through a proxy):

<!-- ~/.m2/settings.xml -->
<settings>
  <proxies>
    <proxy>
      <id>corporate-proxy</id>
      <active>true</active>
      <protocol>http</protocol>
      <host>proxy.yourcompany.com</host>
      <port>8080</port>
      <username>proxyuser</username>
      <password>proxypass</password>
      <nonProxyHosts>localhost|127.0.0.1|*.yourcompany.com</nonProxyHosts>
    </proxy>
  </proxies>
</settings>

Mirror configuration (use a faster regional Maven Central mirror):

<settings>
  <mirrors>
    <mirror>
      <id>central-asia</id>
      <mirrorOf>central</mirrorOf>
      <url>https://repo1.maven.org/maven2</url>
    </mirror>
  </mirrors>
</settings>

Server credentials (for deploying to a private repository):

<settings>
  <servers>
    <server>
      <id>nexus-releases</id>
      <username>deploy-user</username>
      <password>${env.NEXUS_PASSWORD}</password>
    </server>
  </servers>
</settings>

Using ${env.NEXUS_PASSWORD} pulls the password from an environment variable rather than storing it in plain text — the correct approach for CI/CD environments and shared machines.

Using Maven with Apache Tomcat for WAR Deployment

Maven and Tomcat work together naturally — Maven packages the WAR, Tomcat deploys it. Add the Tomcat Maven Plugin to your pom.xml for direct deployment from the command line:

<build>
  <plugins>
    <!-- Change packaging from jar to war -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-war-plugin</artifactId>
      <version>3.4.0</version>
    </plugin>

    <!-- Tomcat 10/11 deployment plugin -->
    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <artifactId>tomcat10-maven-plugin</artifactId>
      <version>2.0-beta-1</version>
      <configuration>
        <url>http://localhost:8080/manager/text</url>
        <serverId>tomcat-local</serverId>
        <path>/my-app</path>
      </configuration>
    </plugin>
  </plugins>
</build>

Add Tomcat credentials to ~/.m2/settings.xml:

<servers>
  <server>
    <id>tomcat-local</id>
    <username>manager</username>
    <password>YOUR_TOMCAT_MANAGER_PASSWORD</password>
  </server>
</servers>

Deploy directly to Tomcat:

# Package and deploy in one command
mvn clean package tomcat10:deploy

# Redeploy (update existing deployment)
mvn clean package tomcat10:redeploy

# Undeploy
mvn tomcat10:undeploy

For a complete Tomcat 11 setup to deploy to, see our Apache Tomcat 11 on Ubuntu 26.04 guide.

Maven in CI/CD with GitHub Actions

A complete GitHub Actions workflow that builds and tests a Maven project on every push:

# .github/workflows/build.yml
name: Java CI with Maven

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout source code
        uses: actions/checkout@v4

      - name: Set up Java 21
        uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'
          cache: maven        # Cache ~/.m2 between runs

      - name: Build with Maven
        run: mvn clean verify --batch-mode --no-transfer-progress

      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-results
          path: target/surefire-reports/

      - name: Upload JAR artifact
        uses: actions/upload-artifact@v4
        with:
          name: application-jar
          path: target/*.jar

Key flags for CI environments:

  • --batch-mode — disables interactive prompts and uses non-colorized output suitable for logs
  • --no-transfer-progress — suppresses the download progress bars that flood CI logs
  • cache: maven — caches ~/.m2/repository between workflow runs, dramatically speeding up builds once dependencies are cached

Maven vs Gradle: Which Build Tool to Choose

Apache MavenGradle
ConfigurationXML (pom.xml)Groovy/Kotlin DSL (build.gradle)
Build speedModerateFaster (incremental builds, build cache)
Learning curveModerate (XML is verbose)Higher (DSL requires learning)
ConventionStrong (opinionated, standardized)Flexible (more configuration needed)
EcosystemLargest (Maven Central, widest plugin support)Large (compatible with Maven repos)
IDE supportExcellent (IntelliJ, Eclipse, VS Code)Excellent
AndroidNot usedAndroid’s official build tool
Spring Boot defaultMavenBoth supported
Enterprise adoptionVery highHigh and growing

Choose Maven when:

  • Your team is already familiar with it
  • You’re working on a Spring Boot or Java EE project (Maven is the default)
  • You want convention over configuration and a highly standardized build
  • You need the widest plugin ecosystem

Choose Gradle when:

  • You’re building Android apps (Gradle is mandatory)
  • Build speed is critical (Gradle’s incremental builds and build cache are significantly faster for large projects)
  • You prefer a concise build file over XML
  • You need highly customized build logic

Common Issues and Quick Fixes

SymptomLikely CauseFix
mvn: command not foundPATH not set, or new shell not sourcedRun source /etc/profile.d/maven.sh or open a new terminal
JAVA_HOME not set errorJAVA_HOME not exported before running MavenSet JAVA_HOME in /etc/profile.d/maven.sh and source it
Wrong Maven version shownAPT and manual Maven both installed, wrong one on PATHRun which mvn to see which binary is active; check PATH order
Downloads fail / connection timeoutCorporate proxy not configuredAdd proxy settings to ~/.m2/settings.xml
BUILD FAILURE — test failuresUnit tests failingRun mvn test and read target/surefire-reports/ for details
Slow builds downloading dependenciesNo dependency cache, or slow Maven CentralAdd a mirror in settings.xml; use -o (offline mode) if all deps are already cached
Permission denied on /opt/mavenWrong ownership after manual installsudo chown -R $USER:$USER /opt/maven

Next Steps

With Maven installed and working, you have the complete Java build toolchain on Ubuntu 26.04:

  • Deploy WAR files to Tomcat — use the Tomcat Maven plugin to go from pom.xml to a running application in one command. See our Apache Tomcat 11 on Ubuntu 26.04 guide for the server setup.
  • Integrate with Apache Kafka — build a Java Kafka producer/consumer application using the kafka-clients dependency, deploy it to Tomcat or as a standalone JAR. See our Apache Kafka on Ubuntu 26.04 guide.
  • Containerize with Docker — package your Maven-built JAR or WAR into a Docker image for consistent deployment. See our Docker on Ubuntu 26.04 guide for the Docker setup.
  • Monitor your Java apps — expose JVM metrics (heap usage, GC, thread count) to Prometheus via JMX Exporter and visualize them in Grafana. See our Prometheus + Grafana monitoring stack guide.
(Visited 2 times, 2 visits today)

You may also like