I'm on Fedora Workstation 40, but similar steps would work on most major Linux distros like Ubuntu/Mint etc
Check existing Java installation
On some Linux distros, Java comes installed by default; however it is just the JRE and not the JDK. You can verify this as java
command is found but the javac
command is NOT found.
java # would show manual of arguments
javac # would give not found error if JDK not installed
java --version # OR "java -version" for older java
javac --version
Refer these articles to know the differences between JDK, JRE and JVM:
- Java Programming Environment and the Java Runtime Environment (JRE)
- What are JDK, JRE, JVM and JIT in Java?
In Fedora, the JREs/JDKs are stored within /usr/lib/jvm
. So you can look into it's contents or query them as:
find /usr/lib/jvm -name java
find /usr/lib/jvm -name javac
Installing an OpenJDK
I'm on Fedora 40 where the package manager is dnf
. You would be installing your desired OpenJDK via your respective Linux distro's package manager (like apt
for Ubuntu/Debian):
- Search available JDKs to install:
dnf search jdk
You would get a list of packages available to install having various Java versions as well as the variant suffix in the package. The headless
variants usually just include the JRE. To install the full JDK with all the necessary tools for Java development, we need the development variant of the package, usually containing the -devel
term suffix in the name for dnf
. Here's a list of few package variant names for Java 17 OpenJDK from the dnf
output:
java-17-openjdk.x86_64 : OpenJDK 17 Runtime Environment
java-17-openjdk-devel.x86_64 : OpenJDK 17 Development Environment
java-17-openjdk-devel-fastdebug.x86_64 : OpenJDK 17 Development Environment optimised with full debugging on
java-17-openjdk-devel-slowdebug.x86_64 : OpenJDK 17 Development Environment unoptimised with full debugging on
java-17-openjdk-fastdebug.x86_64 : OpenJDK 17 Runtime Environment optimised with full debugging on
java-17-openjdk-headless.x86_64 : OpenJDK 17 Headless Runtime Environment
java-17-openjdk-headless-fastdebug.x86_64 : OpenJDK 17 Runtime Environment optimised with full debugging on
java-17-openjdk-headless-slowdebug.x86_64 : OpenJDK 17 Runtime Environment unoptimised with full debugging on
java-17-openjdk-javadoc.x86_64 : OpenJDK 17 API documentation
java-17-openjdk-portable.x86_64 : OpenJDK 17 Runtime Environment portable edition
java-17-openjdk-portable-devel.x86_64 : OpenJDK 17 Development Environment portable edition
java-17-openjdk-portable-sources.x86_64 : OpenJDK 17 full patched sources of portable JDK
java-17-openjdk-slowdebug.x86_64 : OpenJDK 17 Runtime Environment unoptimised with full debugging on
java-17-openjdk-src.x86_64 : OpenJDK 17 Source Bundle
java-17-openjdk-src-fastdebug.x86_64 : OpenJDK 17 Source Bundle for packages with debugging on and optimisation
java-17-openjdk-src-slowdebug.x86_64 : OpenJDK 17 Source Bundle for packages with debugging on and no optimisation
On Ubuntu,, there are lesser packages and the one you want to install is typically named like openjdk-17-jdk
for the whole JDK toolset
- Install your desired OpenJDK package from that list
# Installing the latest OpenJDK with optimized debugging
sudo dnf install java-latest-openjdk-devel-fastdebug
# Installing a specific version like OpenJDK 17
sudo dnf install java-17-openjdk-devel
- Verify installation by checking
java
andjavac
commands are found
Installing an Oracle JDK
Visit the Official Oracle SE Downloads Page. Locate your required Java version's downloads section
Download the appropriate package for your platform. For RedHat based Linux distros like Fedora, download the
.rpm
package (and.deb
for Ubuntu/Debian). Before downloading, you'll have to sign-in to Oracle and agree to the termsDouble click on the downloaded file (like
jdk-11.0.24_linux-x64_bin.rpm
) and selectInstall
. It will install and configure the Oracle JDK.Now that OracleJDK is installed, verify the
java
andjavac
commands being detected
Installing JDKs via IntelliJ
You can also install JDKs from within IntelliJ itself:
- Click on the Gear icon ⚙️ and then go into
Project Structure
. SelectSDKs
, click+
plus icon. Then select the JDK you wish to be downloaded and installed - The JDK is installed in the
~/.jdks
folder, for example:~/.jdks/openjdk-20.0.2/
IntelliJ auto-detects your available JDK locations on your system. You can also add your existing JDK folder locations like /usr/lib/jvm/jdk-11-oracle-x64
under configured JDKs in Project Structure
Working with multiple Java installations
The update-alternatives
command in Linux (also called just alternatives
in Fedora) creates, removes, maintains and displays information about the symbolic links comprising the alternatives system.
It is possible for several programs fulfilling the same or similar functions to be installed on a single system at the same time. A generic name in the filesystem is shared by all files providing interchangeable functionality. The alternatives system helps determine which actual file is referenced by this generic name.
Useful references:
When you install OpenJDK via your package manager or Oracle-JDK from the downloaded file, the alternatives should automatically get updated during that process
View available options for a command
update-alternatives --display java
The output would look like:
java - status is manual.
link currently points to /usr/lib/jvm/java-21-openjdk-21.0.4.0.7-2.fc40.x86_64/bin/java
/usr/lib/jvm/java-21-openjdk-21.0.4.0.7-2.fc40.x86_64/bin/java - family java-21-openjdk.x86_64 priority 21000407
... follower links ...
/usr/lib/jvm/jdk-11.0.24-oracle-x64/bin/java - priority 184745984
... follower links ...
/usr/lib/jvm/java-22-openjdk-22.0.2.0.9-1.rolling.fc40.x86_64-fastdebug/bin/java - family java-latest-openjdk.x86_64 priority 1
... follower links ...
Current `best' version is /usr/lib/jvm/jdk-11.0.24-oracle-x64/bin/java.
Similarly, see alternative options list for javac
Adding an alternatives entry for a command
If any alternative for your commands is NOT registered in the list, you can manually add them as:
sudo update-alternatives --install <link> <name> <path> <priority>
For example, I downloaded the JetBrains Runtime (JCEF) JDK from within IntelliJ, which was downloaded at ~/.jdks/jbrsdk_jcef-17.0.12/
folder; but it was not showing up in the alternatives list. So, I'll add the alternatives entry for java
and javac
as:
sudo update-alternatives --install /usr/bin/java java ~/.jdks/jbrsdk_jcef-17.0.12/bin/java 138
sudo update-alternatives --install /usr/bin/javac javac ~/.jdks/jbrsdk_jcef-17.0.12/bin/javac 138
Similarly, add alternatives for more commands like jar
, javadoc
etc. as required
You can also add follower links as:
--install link name path priority [--follower link name path]... [--initscript service] [--family name]
Switching between available alternatives of a command
Pick between Java installations present
sudo update-alternatives --config java
The output would look like below. Note that *
denotes best available version and +
denotes your current selection:
There are 4 programs which provide 'java'.
Selection Command
-----------------------------------------------
+ 1 java-latest-openjdk.x86_64 (/usr/lib/jvm/java-23-openjdk-23.0.0.0.37-1.rolling.fc40.x86_64-fastdebug/bin/java)
* 2 /usr/lib/jvm/jdk-11.0.24-oracle-x64/bin/java
3 java-21-openjdk.x86_64 (/usr/lib/jvm/java-21-openjdk-21.0.5.0.11-1.fc40.x86_64/bin/java)
4 /home/kumar/.jdks/jbrsdk_jcef-17.0.12/bin/java
Enter to keep the current selection[+], or type selection number:
Similarly, choose among the alternative options for javac
When you uninstall/remove your JDK packages, remember to delete the respective alternatives entries too
Removing an alternatives entry
For example, to remove the JCEF JDK's java
command alternative entry:
sudo update-alternatives --remove java ~/.jdks/jbrsdk_jcef-17.0.12/bin/java
Add Java to PATH
This should not be necessary if you are following the
update-alternatives
method to manage between Java installations and all entries are complete
However, to manually set the configuration in your shell profile, you can do as below:
- Set Environment Variables in your Shell config file (i.e.
~/.zshrc
,~/.bashrc
etc.)
# Set "JAVA_HOME" environment variable to the jdk folder path
export JAVA_HOME=/usr/lib/jvm/jdk-11-oracle-x64
# Add the binaries within JAVA_HOME like 'java', 'javac' to PATH
export PATH=$PATH:$JAVA_HOME/bin
- Restart SHELL:
exec $(which $SHELL)
- Now,
java
should be detected successfully
[kumar@lenovo-s340 ~]$ java --version
java 11.0.22 2024-01-16 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.22+9-LTS-219)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.22+9-LTS-219, mixed mode)
[kumar@lenovo-s340 ~]$ javac --version
javac 11.0.22
Top comments (2)
SdkMan is a good alternative if you don't want to deal with all the above.
Yes, it is a popular external Bash script, while the
alternatives
system is in-built in Linux that you can configure for selections of other binaries too