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.
| Method | Source or Channel | Update Behavior | Best Fit | Trade-offs |
|---|---|---|---|---|
| DNF package | Fedora maven package | Updated with normal DNF upgrades | Most Fedora workstations, servers, and CI hosts | May lag behind Apache’s recommended Maven 3 release |
| Official tarball | Apache Maven downloads | Manual verified update or optional update-maven helper | Newest upstream Maven 3 release or pinned project versions | Requires 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/repositoryremoves 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.


Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags currently allowed in published comments:
<code>command</code>command<strong>bold</strong><em>italic</em><a href="https://example.com">link</a><blockquote>quote</blockquote>