Setting up Java on Linux means choosing the installation directory a program should use. JAVA_HOME is an environment variable that names that Java installation directory.
I’ll show you how to find the JDK root and set JAVA_HOME for the shell or system that runs your program.
TL;DR: Set JAVA_HOME to the JDK directory
Set JAVA_HOME to the root of the Java Development Kit, then put that export in the startup file your shell actually reads. The variable names the installation directory, while PATH tells the shell where to find commands.
- Find the JDK root by resolving the java executable and removing /bin/java.
- Export JAVA_HOME for the current shell, then save it in the matching user startup file.
- Verify both the variable and the java executable path in a new shell.
What is JAVA_HOME in Linux?
JAVA_HOME is an environment variable that points to a Java installation directory. It gives a program a stable starting point for files beneath that installation.
A JDK root contains a bin directory with its Java executables.
| Value | What it identifies | Example |
|---|---|---|
| JAVA_HOME | Java installation root | /opt/jdk/21 |
| JAVA_HOME/bin | Directory containing Java commands | /opt/jdk/21/bin |
| PATH | Directories searched for commands | $JAVA_HOME/bin followed by existing entries |
| java | Command found through PATH, sometimes a symlink | /usr/bin/java |
A project and an interactive shell can resolve different Java installations.
The guide to running a command-line Java program on Linux covers compiling and launching a program after the JDK is available.
How to set JAVA_HOME on Linux step by step
First locate the Java installation that should be used, then export its root directory in the correct shell configuration file. A build also requires the compiler executable, javac.
Step 1: Check whether a JDK is installed
Check the Java commands before setting a home directory. The following read-only script was run in this refresh, and its screenshot shows the exact captured output.
#!/usr/bin/env bash
printf 'JAVA_HOME=%s\n' "${JAVA_HOME-}"
command -v java || true
java -version 2>&1 || true
command -v javac || true
The file is named java-home-check.sh; run it with bash java-home-check.sh. The captured output is:
JAVA_HOME=
/usr/bin/java
openjdk version "25.0.4.1" 2026-08-18
OpenJDK Runtime Environment (build 25.0.4.1+1-1-24.04.4-Ubuntu)
OpenJDK 64-Bit Server VM (build 25.0.4.1+1-1-24.04.4-Ubuntu, mixed mode, sharing)
/usr/bin/javac

I ran bash java-home-check.sh and found Java and javac available, with JAVA_HOME empty. The output shows Java and javac are available, but JAVA_HOME is unset.
Step 2: Find the JDK installation directory
Resolve the command path because distributions may expose Java through alternatives or symbolic links.
readlink -f "$(command -v java)"
readlink -f "$(command -v javac)"
If the resolved path ends in /usr/lib/jvm/example-jdk/bin/java, use /usr/lib/jvm/example-jdk as the candidate root.
Package-managed JDKs often use versioned directories under /usr/lib/jvm. Manually unpacked archives may use another location.
Step 3: Set JAVA_HOME in the current shell
Export the installation root so commands launched from this shell inherit it.
export JAVA_HOME=/usr/lib/jvm/example-jdk
Add the JDK bin directory to PATH only if this shell should select its commands.
export PATH="$JAVA_HOME/bin:$PATH"
This puts the selected JDK commands ahead of later matching PATH entries.
Step 4: Save the value in the startup file your shell reads
Choose a file according to how the shell starts. Bash uses ~/.bashrc for interactive non-login shells. Login Bash reads /etc/profile and then its first available user login file.
| Shell/session | Common user file | When to choose it |
|---|---|---|
| Interactive Bash terminal | ~/.bashrc | Terminal reads this file as an interactive non-login shell |
| Bash login session | ~/.bash_profile, ~/.bash_login or ~/.profile | Use the first existing login file in Bash’s order |
| Interactive Zsh | ~/.zshrc | Use for settings needed in interactive Zsh sessions |
| System-wide login setup | /etc/profile.d/*.sh or distribution guidance | Use only when all users or services need the value |
Check the shell name and whether the session is a login shell before choosing a file. The guide to Linux shell types explains how the command interpreter differs from the terminal.
Add these lines to the selected user file, replacing the example directory with the verified root.
export JAVA_HOME=/usr/lib/jvm/example-jdk
export PATH="$JAVA_HOME/bin:$PATH"
Read the selected file before adding an export. Read the file first so an existing export is not duplicated.
Step 5: Choose a system-wide setting only when needed
Red Hat’s OpenJDK guidance documents /etc/bashrc for system-wide shell settings and ~/.bashrc for one user. Follow the distribution’s current documentation when the host uses a different configuration.
Services may start without reading interactive shell files. Configure the environment through the service or application launch mechanism when that is the consumer.
Choose shared configuration only when every account should use the same JDK.
This refresh does not edit system configuration. For an administrative change, first confirm the desired JDK directory and which sessions should receive the value. Then use the distro’s documented method and verify it from a newly launched target session.
Step 6: Reload the configuration and verify the value
Source the file you edited to apply it now. Then open a new terminal of the same type to check persistence.
source ~/.bashrc
printf '%s\n' "$JAVA_HOME"
test -x "$JAVA_HOME/bin/java" && echo "Java found under JAVA_HOME"
test -x "$JAVA_HOME/bin/javac" && echo "Compiler found under JAVA_HOME"
The first check prints the configured directory. The executable tests confirm whether that directory contains the expected tools. They do not install Java or change system settings.
A desktop application keeps the environment it received when it started. Restart it from the intended session or set its documented environment value.
Why is JAVA_HOME empty or incorrect?
An empty or rejected JAVA_HOME usually means the active shell did not read its export, the value names the wrong directory, or the application received a different environment. Check the symptom before editing another file.
| Case | Symptom | Fix |
|---|---|---|
| Unset variable | echo “$JAVA_HOME” prints nothing | Check shell type and login-file order, then source the file containing the export |
| Wrong root | JAVA_HOME/bin/java is missing | Resolve java and set the installation root containing bin/java |
| Missing compiler | Java works but a build tool reports no JDK | Check for executable bin/javac and set the required JDK root |
| Different app environment | Terminal is correct but GUI app is not | Restart from the intended session or set the app environment |
| PATH mismatch | java and JAVA_HOME appear to disagree | Compare command -v java with “$JAVA_HOME/bin/java” |
A build script that consults both JAVA_HOME and java can select different installations. Compare the resolved paths with readlink -f “$JAVA_HOME/bin/java” and readlink -f “$(command -v java)”. Matching paths show both lookups reach the same Java executable.
Quote a path containing spaces in both assignments and expansions. An unquoted value is split into separate shell arguments, so later commands may receive the wrong path.
Also check that the account running Java can read and traverse the directory. A value may be spelled correctly but point to a moved or inaccessible location. Test for an executable under JAVA_HOME to distinguish a bad root from a Java command that is absent from PATH.
For Bash login sessions, only the first existing user login file is read after /etc/profile, so an existing ~/.bash_profile must load ~/.profile explicitly if the export is stored there.
Use a documented system-wide file when multiple login sessions need the same value. Services can bypass those files. Configure a service through its own environment mechanism when necessary.
Containers and services can define a separate launch environment. Check the relevant configuration and identify which process starts the application before changing a shell file.
A shell export reaches child processes launched from that shell.
Common JAVA_HOME errors and next checks
Compare the configured root with the Java installation and the process that consumes it. Use the symptom table before changing another file.
- A hosting panel or shell script reports no Java home: check the account and launch method used by that process. A terminal variable does not configure another account automatically.
- JAVA_HOME names a folder but Java cannot start: run test -x “$JAVA_HOME/bin/java” and inspect permissions on each directory in the path.
- A build selects a different compiler: compare “$JAVA_HOME/bin/javac” with command -v javac. The first is under the chosen home. The second shows PATH selection.
For VPS hosting, check the provider’s image or control panel documentation before assuming a JDK is preinstalled. Hosting plans and managed panels can expose Java through different accounts or service launchers. Set the variable for the account that runs the application, and avoid changing a shared system file when only one deployment needs a particular JDK.
After changing a startup file, test a fresh session rather than relying only on the existing terminal. If an application still sees an old value, restart it through its normal service or panel workflow, then inspect its documented environment configuration. Do not use a shell startup file as a substitute for a service setting unless the service actually launches that shell.
Use one assignment for each intended scope. Keep project-specific Java versions in the project or service configuration rather than changing a shared value.
Conclusion: Verify the JDK root and shell scope
Confirm that the Java tools and application read the same intended installation. For more context, see our guides to Bash profile and bashrc files, setting environment variables in Linux, and installing OpenJDK on Linux.
FAQ
These answers cover the path and persistence questions that commonly follow a JAVA_HOME setup.
How do I find the Java installation directory on Linux?
Resolve the path from command -v java with readlink -f, then remove the final /bin/java components. Confirm the candidate root contains the tools you need, such as bin/java and bin/javac.
Should JAVA_HOME point to bin/java?
No. Set JAVA_HOME to the Java installation root, such as /usr/lib/jvm/example-jdk. Tools can add /bin or another subdirectory themselves.
Which file should I use to set JAVA_HOME for Bash?
Use ~/.bashrc for an interactive non-login Bash shell. Login Bash reads /etc/profile and then the first available file among ~/.bash_profile, ~/.bash_login and ~/.profile. Choose the file that matches how the shell starts.
How can I make JAVA_HOME available to all users?
Use the distribution’s documented system-wide environment configuration, such as /etc/profile.d where supported. Administrative changes affect other users, and services may need a separate environment setting.
