How to Install Apache Maven on Fedora 44

Install Apache Maven on Fedora 44 with the DNF package for Fedora-managed updates or the official tarball when a project needs a newer Maven 3 release under /opt. The workflow includes Java checks, a quickstart build, manual or helper-based tarball updates, cache cleanup, proxy setup, and removal.

Last updatedAuthorJoshua JamesRead time8 minGuide typeFedora

Java projects that depend on Maven need the mvn launcher, a working JDK compiler, and a build check that reaches Maven Central. To install Apache Maven on Fedora, start with the DNF package for Fedora-managed updates, then use the Apache tarball only when a project needs a newer or pinned upstream Maven 3 release.

Maven reads each project’s pom.xml, downloads required libraries from Maven Central or configured repositories, and runs lifecycle phases such as compile, test, and package. The Fedora package keeps that workflow inside normal DNF maintenance, while the tarball method trades package-manager updates for upstream release cadence and a stable /opt/maven prefix.

Install Apache Maven on Fedora

Choose an Apache Maven Method on Fedora

Use DNF for most Fedora systems because it installs Maven with Fedora’s OpenJDK dependency chain and updates through the same package workflow as the rest of the system. Choose the official Apache tarball only when you need an upstream Maven 3 release newer than Fedora’s package, or when a CI host or project policy needs Maven under /opt.

MethodSource or ChannelUpdate BehaviorBest FitTrade-offs
DNF packageFedora maven packageUpdated with normal DNF upgradesMost Fedora workstations, servers, and CI hostsMay lag behind Apache’s recommended Maven 3 release
Official tarballApache Maven downloadsManual verified update or optional update-maven helperNewest upstream Maven 3 release or pinned project versionsRequires PATH setup and manual lifecycle management

The Apache name in Apache Maven refers to the Apache Software Foundation project, not the Apache HTTP Server. Fedora’s web server package is httpd; use the separate guide to install Apache HTTPD on Fedora if you need the web server instead.

Apache publishes both .tar.gz and .zip binary archives. The Fedora commands use the .tar.gz archive because it works naturally with Fedora’s standard shell tools and keeps the installed files under one versioned directory. Maven 4 is still a preview branch on Apache’s download page, so keep production Fedora systems on Maven 3 unless you are testing migration work.

Refresh Fedora Before Installing Maven

Refresh repository metadata and apply pending package updates before installing Maven:

sudo dnf upgrade --refresh

The --refresh option tells DNF to reload package metadata before resolving the transaction, which avoids stale package lists on systems that have not updated recently.

Install Apache Maven with DNF

Install Maven from Fedora’s default repositories:

sudo dnf install maven

Fedora resolves Maven’s Java dependencies during the transaction. On Fedora 44 package metadata, the Maven package uses the maven-openjdk25 binding and pulls in java-25-openjdk-devel when the matching JDK is not already present.

Confirm the installed RPMs when you want package-level proof:

rpm -q maven maven-openjdk25 java-25-openjdk-devel

Example Fedora 44 output uses this package shape:

maven-3.9.11-11.fc44.noarch
maven-openjdk25-3.9.11-11.fc44.noarch
java-25-openjdk-devel-25.0.3.0.9-2.fc44.x86_64

Verify the active Maven binary and Java runtime:

mvn -version

The version, kernel, and locale lines can differ after Fedora updates, but Maven home should point to Fedora’s packaged location:

Apache Maven 3.9.11 (Red Hat 3.9.11-11)
Maven home: /usr/share/maven
Java version: 25.0.3, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-25-openjdk
Default locale: en_AU, platform encoding: UTF-8
OS name: "linux", version: "7.0.6-200.fc44.x86_64", arch: "amd64", family: "unix"

Install Apache Maven from the Official Tarball

The tarball method installs Maven under /opt and uses Apache’s checksum file to verify the downloaded archive before extraction. Do not install both methods unless you intentionally want a packaged Maven under /usr/bin and a manually managed Maven under /opt; the command that wins depends on $PATH order.

Install Java and Download Tools for Maven

Install the OpenJDK development package and download tools needed by the tarball workflow:

sudo dnf install java-25-openjdk-devel curl tar gzip

Maven 3.9 runs on JDK 8 or newer, but a full JDK is still the practical choice for Fedora build hosts because Maven projects often need javac, jar, and related development tools. This example uses the same OpenJDK branch as Fedora’s Maven package binding; if you choose another JDK, verify java, javac, and Maven’s runtime line before building.

Detect the Current Apache Maven 3 Release

Use Apache’s Maven download page as the release source and extract the current Maven 3 binary tarball version:

MAVEN_VERSION=
MAVEN_PAGE=
if cd /tmp; then
  MAVEN_PAGE=$(curl -fsSL https://maven.apache.org/download.cgi)
  MAVEN_VERSION=$(printf '%s\n' "$MAVEN_PAGE" | grep -oE 'apache-maven-3\.[0-9.]+-bin\.tar\.gz' | sed -E 's/apache-maven-([0-9.]+)-bin\.tar\.gz/\1/' | sort -Vu | tail -n 1)
fi

if [ -n "$MAVEN_VERSION" ]; then
  printf 'Maven version: %s\n' "$MAVEN_VERSION"
else
  echo "Could not detect the current Maven 3 release." >&2
fi

The curl command in Linux retrieves the Apache page, while grep command filtering and sed command substitution keep only Maven 3 binary tarball versions. Continue only after the command prints a version, because the download steps reuse the same variable in the same terminal session.

Download and Verify the Maven Tarball

Download the binary tarball and its SHA-512 checksum from Apache:

curl -fsSLO "https://dlcdn.apache.org/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz"
curl -fsSLO "https://downloads.apache.org/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz.sha512"

Apache’s SHA-512 file contains only the hash, so pair it with the local filename before running sha512sum:

printf '%s  apache-maven-%s-bin.tar.gz\n' "$(cat "apache-maven-$MAVEN_VERSION-bin.tar.gz.sha512")" "$MAVEN_VERSION" | sha512sum -c -

A successful verification prints an OK result for the downloaded archive:

apache-maven-3.9.16-bin.tar.gz: OK

Extract Maven Under /opt

Extract the verified archive and point /opt/maven at the active version:

sudo tar -xzf "apache-maven-$MAVEN_VERSION-bin.tar.gz" -C /opt
sudo ln -sfn "/opt/apache-maven-$MAVEN_VERSION" /opt/maven

The symbolic link lets future tarball updates switch Maven versions without rewriting every shell profile. The archive is a standard .tar.gz file; the guide to open gz and tgz files in Linux explains the archive format if you need more background.

Add Maven to the System PATH

Create a profile script that makes the manually installed Maven binary available in new login shells:

sudo tee /etc/profile.d/maven.sh > /dev/null <<'EOF'
if [ -d /opt/maven/bin ]; then
  case ":$PATH:" in
    *:/opt/maven/bin:*) ;;
    *) PATH="/opt/maven/bin:$PATH" ;;
  esac
  export PATH
fi
EOF

The guard adds /opt/maven/bin only when it is missing from $PATH, so repeated source commands do not duplicate the entry. Load the profile script in the current shell, or open a new terminal session:

source /etc/profile.d/maven.sh
hash -r

Confirm the shell resolves the tarball-managed Maven first:

command -v mvn
mvn -version | sed -n 's/^Apache Maven \([0-9.]*\).*/Apache Maven \1/p; /^Maven home:/p'

The tarball method should report Maven home under /opt:

/opt/maven/bin/mvn
Apache Maven 3.9.16
Maven home: /opt/maven

Build a Test Apache Maven Project on Fedora

A sample project verifies more than the mvn command path. It confirms Maven can reach Maven Central, resolve plugins, create a project structure, and produce a JAR.

cd ~
mvn -B archetype:generate \
  -DarchetypeGroupId=org.apache.maven.archetypes \
  -DgroupId=com.example \
  -DartifactId=maven-check \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DarchetypeVersion=1.5 \
  -DjavaCompilerVersion=17 \
  -DinteractiveMode=false
cd maven-check
mvn -B package

The official quickstart archetype uses Java 17 compiler settings by default, which keeps the sample build compatible with modern Fedora JDK packages. Newer JDKs can still print dependency-stack warnings before the build logs continue; treat the final build status as the success signal:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

The generated project includes pom.xml, Maven config files under .mvn/, Java source files under src/main/java, test files under src/test/java, and a packaged JAR under target/. Remove the sample directory when you no longer need it:

cd ~
rm -rf maven-check

For real projects, install Git on Fedora before cloning source repositories, and install Docker on Fedora when your Maven builds depend on containerized databases, test services, or deployment images.

Manage Apache Maven Updates on Fedora

Update DNF-Installed Maven

DNF-managed Maven updates with Fedora packages:

sudo dnf upgrade --refresh maven

A normal full-system upgrade also updates Maven when Fedora publishes a new package build:

sudo dnf upgrade --refresh

Update Tarball-Installed Maven

The tarball method is outside Fedora’s package manager, so updates must repeat Apache release detection, checksum verification, extraction, and the /opt/maven symlink switch. Use the manual block when you want to inspect each phase, or install the helper when this host will track upstream Maven 3 releases over time.

Run a Manual Maven Tarball Update

The manual update path keeps every step visible and updates /opt/maven only when Apache publishes a newer Maven 3 binary tarball:

MAVEN_VERSION=
MAVEN_PAGE=
CURRENT_VERSION=
if cd /tmp; then
  MAVEN_PAGE=$(curl -fsSL https://maven.apache.org/download.cgi)
  MAVEN_VERSION=$(printf '%s\n' "$MAVEN_PAGE" | grep -oE 'apache-maven-3\.[0-9.]+-bin\.tar\.gz' | sed -E 's/apache-maven-([0-9.]+)-bin\.tar\.gz/\1/' | sort -Vu | tail -n 1)
  CURRENT_VERSION=$(/opt/maven/bin/mvn -version 2>/dev/null | sed -n 's/^Apache Maven \([0-9.]*\).*/\1/p' | tail -n 1 || true)
else
  echo "Could not use /tmp as the download directory." >&2
fi

if [ -z "$MAVEN_VERSION" ]; then
  echo "Could not detect the current Maven 3 release." >&2
elif [ "$CURRENT_VERSION" = "$MAVEN_VERSION" ]; then
  printf 'Current: %s\nLatest:  %s\n' "${CURRENT_VERSION:-none}" "$MAVEN_VERSION"
  echo "Maven is already current."
else
  printf 'Current: %s\nLatest:  %s\n' "${CURRENT_VERSION:-none}" "$MAVEN_VERSION"
  curl -fsSLO "https://dlcdn.apache.org/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz"
  curl -fsSLO "https://downloads.apache.org/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz.sha512"
  printf '%s  apache-maven-%s-bin.tar.gz\n' "$(cat "apache-maven-$MAVEN_VERSION-bin.tar.gz.sha512")" "$MAVEN_VERSION" | sha512sum -c -
  sudo tar -xzf "apache-maven-$MAVEN_VERSION-bin.tar.gz" -C /opt
  sudo ln -sfn "/opt/apache-maven-$MAVEN_VERSION" /opt/maven
  hash -r
  /opt/maven/bin/mvn -version
fi

If the installed tarball is already current, the manual block stops before downloading. Expect the status lines to look like this, with the version number changing as Apache publishes newer Maven 3 releases:

Current: 3.9.16
Latest:  3.9.16
Maven is already current.

This block leaves older /opt/apache-maven-* directories in place so you can roll back the symlink manually if a project fails after an upstream Maven change. Remove old directories only after your builds pass with the new version.

Create a Reusable update-maven Helper

For build hosts that use the tarball method repeatedly, create a guarded helper in /usr/local/bin. The setup refuses to overwrite an unrelated existing command, then writes an article-owned update-maven script:

if [ -e /usr/local/bin/update-maven ] && ! grep -q 'LinuxCapable Apache Maven updater' /usr/local/bin/update-maven 2>/dev/null; then
  echo "Refusing to overwrite existing /usr/local/bin/update-maven" >&2
  false
else
  sudo install -d -m 0755 /usr/local/bin
  sudo tee /usr/local/bin/update-maven > /dev/null <<'EOF'
#!/usr/bin/env bash
# LinuxCapable Apache Maven updater
set -euo pipefail

install_parent=/opt
link_path=/opt/maven
stage_dir=
work_dir=$(mktemp -d)

cleanup() {
  rm -rf "$work_dir"
  if [ -n "$stage_dir" ]; then
    sudo rm -rf "$stage_dir" >/dev/null 2>&1 || true
  fi
}
trap cleanup EXIT

for cmd in curl grep sed sort tail sha512sum tar sudo mktemp java; do
  if ! command -v "$cmd" >/dev/null 2>&1; then
    echo "Missing required command: $cmd" >&2
    exit 1
  fi
done

page=$(curl -fsSL https://maven.apache.org/download.cgi)
latest=$(printf '%s\n' "$page" | grep -oE 'apache-maven-3\.[0-9.]+-bin\.tar\.gz' | sed -E 's/apache-maven-([0-9.]+)-bin\.tar\.gz/\1/' | sort -Vu | tail -n 1)

if [ -z "$latest" ]; then
  echo "Could not detect the current Maven 3 release." >&2
  exit 1
fi

current=$("$link_path/bin/mvn" -version 2>/dev/null | sed -n 's/^Apache Maven \([0-9.]*\).*/\1/p' | tail -n 1 || true)
printf 'Current: %s\nLatest:  %s\n' "${current:-none}" "$latest"

if [ "$current" = "$latest" ]; then
  echo "Maven is already current."
  exit 0
fi

cd "$work_dir"
archive="apache-maven-$latest-bin.tar.gz"
checksum="$archive.sha512"
curl -fsSLO "https://dlcdn.apache.org/maven/maven-3/$latest/binaries/$archive"
curl -fsSLO "https://downloads.apache.org/maven/maven-3/$latest/binaries/$checksum"
printf '%s  %s\n' "$(cat "$checksum")" "$archive" | sha512sum -c -

target_dir="$install_parent/apache-maven-$latest"
if [ -e "$target_dir" ] && [ ! -x "$target_dir/bin/mvn" ]; then
  echo "$target_dir exists but does not contain bin/mvn; refusing to overwrite it." >&2
  exit 1
fi

if [ ! -x "$target_dir/bin/mvn" ]; then
  stage_dir=$(sudo mktemp -d -p "$install_parent" ".apache-maven-$latest.XXXXXX")
  sudo tar -xzf "$archive" -C "$stage_dir" --strip-components=1
  sudo test -x "$stage_dir/bin/mvn"
  sudo chmod -R a+rX "$stage_dir"
  sudo mv -T "$stage_dir" "$target_dir"
  stage_dir=
fi

if [ -e "$link_path" ] && [ ! -L "$link_path" ]; then
  echo "$link_path exists and is not a symlink; refusing to replace it." >&2
  exit 1
fi

sudo ln -sfn "$target_dir" "$link_path"
hash -r
"$link_path/bin/mvn" -version
EOF

  sudo chmod 0755 /usr/local/bin/update-maven
  command -v update-maven
fi

The final command should print the helper path:

/usr/local/bin/update-maven

Run the helper manually when you are ready to check for an upstream Maven 3 update:

update-maven

An already-current helper run should match the no-op status shown in the manual path. When an upstream update is available, the first two lines differ, the checksum line must end in OK, and the final Maven output should still report /opt/maven as Maven home:

Current: 3.9.15
Latest:  3.9.16
apache-maven-3.9.16-bin.tar.gz: OK
Apache Maven 3.9.16
Maven home: /opt/maven

The helper prints the current and latest Maven versions, verifies Apache’s SHA-512 checksum before extraction, stages new payloads under /opt, and refuses to replace unrelated /opt/maven or /usr/local/bin/update-maven paths. Like the manual path, it leaves older Maven directories under /opt until you remove them after project testing.

Do not run tarball upgrades unattended from cron. Maven version changes can affect plugins, build extensions, wrapper expectations, and CI output, so review the Maven release history before switching production build hosts to a new upstream release.

Troubleshoot Apache Maven on Fedora

Maven Command Not Found

If mvn is missing after a DNF install, confirm the package is installed:

rpm -q maven
command -v mvn

If the RPM is installed but the command is missing, reinstall the package:

sudo dnf reinstall maven

For tarball installs, confirm the profile script exists and load it in the current shell:

cat /etc/profile.d/maven.sh
source /etc/profile.d/maven.sh
command -v mvn

If command -v mvn still returns nothing, open a new terminal session and check that /opt/maven/bin appears before any older Maven path in $PATH.

Maven Uses the Wrong Java Version

Check the Java binary Maven sees and compare it with Maven’s runtime line:

readlink -f "$(command -v java)"
mvn -version

If multiple JDKs are installed, switch both the runtime and compiler alternatives so Maven and javac stay aligned:

sudo alternatives --config java
sudo alternatives --config javac

Some plugins also read JAVA_HOME. Derive it from the active Java binary instead of hardcoding a stale path:

JAVA_HOME=$(dirname "$(dirname "$(readlink -f "$(command -v java)")")")
printf 'export JAVA_HOME=%s\n' "$JAVA_HOME" | sudo tee /etc/profile.d/java-home.sh > /dev/null
source /etc/profile.d/java-home.sh
printf '%s\n' "$JAVA_HOME"

Fedora’s Java alternatives and permanent JAVA_HOME setup have more edge cases than Maven itself, especially when pinned and rolling OpenJDK packages coexist. Use the guide to set Java environment paths on Fedora when you need a fuller alternatives and JAVA_HOME workflow.

Maven Dependency Downloads Fail or Use Stale Cache

From the project directory that contains pom.xml, force Maven to check remote repositories again before deleting anything:

cd /path/to/your-project
mvn -U clean package

If a dependency cache is corrupted, run Maven’s dependency purge from the same project root so the plugin can read the project’s dependency graph:

mvn dependency:purge-local-repository

Deleting ~/.m2/repository removes downloaded dependencies for your Linux account. Keep project source code and private settings files intact unless you intentionally want a full Maven reset.

rm -rf ~/.m2/repository

Rebuild the project after clearing the cache so Maven downloads fresh artifacts:

mvn -U clean package

Maven Needs a Proxy for Downloads

Corporate networks often require Maven to use an HTTP proxy before it can reach Maven Central. Create a user-level settings file and replace the host and port with your organization’s proxy details:

mkdir -p ~/.m2
cat > ~/.m2/settings.xml <<'EOF'
<settings>
  <proxies>
    <proxy>
      <active>true</active>
      <protocol>http</protocol>
      <host>proxy.example.com</host>
      <port>8080</port>
    </proxy>
  </proxies>
</settings>
EOF

Then test with a command that must contact Maven Central:

mvn -U help:effective-settings

Old Maven Download URLs Return 404

Apache’s main CDN carries current release assets, so older direct URLs such as apache-maven-3.9.6-bin.zip can stop working from dlcdn.apache.org. Use the Apache Maven 3 archive when you must retrieve an old release for compatibility testing, and prefer the current download page for normal Fedora installations.

Remove Apache Maven from Fedora

Remove DNF-Installed Maven

Remove the Fedora Maven package with DNF:

sudo dnf remove maven

DNF may report unused Java or Maven library dependencies after removal. Review the transaction carefully before confirming an autoremove cleanup:

sudo dnf autoremove

Verify that the package is gone:

if rpm -q maven > /dev/null 2>&1; then
  echo "maven is still installed"
else
  echo "maven is not installed"
fi
maven is not installed

Remove Tarball-Installed Maven

Remove the manually installed Maven directory, active symlink, optional update helper, and profile script:

sudo rm -rf /opt/apache-maven-* /opt/maven
sudo rm -f /usr/local/bin/update-maven
sudo rm -f /etc/profile.d/maven.sh
hash -r
command -v mvn || echo "mvn command not found"

If the current shell still resolves an old Maven path, open a new terminal session after removing the profile script.

Remove Maven Cache and User Settings

The next command permanently deletes your Maven settings, downloaded dependencies, credentials stored in settings.xml, and local cache for the current Linux account. Back up any private repository credentials or custom mirror settings first.

rm -rf ~/.m2

Conclusion

Apache Maven is now ready on Fedora through either the low-maintenance DNF package or a verified upstream tarball under /opt. Use DNF for routine developer systems, choose the tarball for pinned upstream versions, and keep Java selection explicit when projects depend on a specific JDK.

Share this guide

Help another Linux user troubleshoot faster

Share this guide with someone troubleshooting Linux systems or saving it for later.

Follow LinuxCapable

Want more LinuxCapable guides in Google?

Add LinuxCapable as a preferred source so Google can show our tutorials more often in Top Stories and mark them as preferred in AI Mode and AI Overviews when relevant.

Add LinuxCapable as a preferred source on Google
Search LinuxCapable

Need another guide?

Search LinuxCapable for package installs, commands, troubleshooting, and follow-up guides related to what you just read.

Found this guide useful?

Support LinuxCapable to keep tutorials free and up to date.

Buy me a coffeeBuy me a coffee
Before commenting, please review our Comments Policy.
Formatting tips for your comment

You can use basic HTML to format your comment. Useful tags currently allowed in published comments:

You type Result
<code>command</code> command
<strong>bold</strong> bold
<em>italic</em> italic
<a href="https://example.com">link</a> link
<blockquote>quote</blockquote> quote block

Add to the discussion

Questions, fixes, command output, and version notes help keep this guide current.

Verify before posting: