Question
I want to use the latest JavaFX, which requires Java 8, on macOS Mavericks with IntelliJ IDEA 13 Community Edition. After running Oracle's Java 8 installer, the JDK appears to be installed at:
/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk
However, older Java versions appear under:
/System/Library/Java/JavaFrameworks/jdk1.6...
I am not sure why Java 8 is installed in /Library instead of /System/Library, or what the difference is. Also, /usr/libexec/java_home does not detect Java 8, so the usual methods for switching Java versions do not work. I also tried adding a symbolic link to make Java 8 appear under the /System/Library path, but that did not help.
Running:
/usr/libexec/java_home -V
still lists only Java 1.6.
At the same time, the Java control panel in System Preferences shows Java 8.
Why does Oracle's installer place Java 8 there, and how can I correctly configure macOS and my development tools to use Java 8?
Short Answer
By the end of this page, you will understand how Java is installed on macOS, why different Java versions appear in different system folders, how java_home discovers JDKs, and how to verify and configure Java 8 for terminal use and IDEs such as IntelliJ IDEA.
Concept
macOS has historically treated Apple's system-provided Java and user-installed Java differently.
Older Apple-provided Java versions were often stored in system-managed locations such as:
/System/Library/Java/JavaFrameworks/
Newer Oracle JDK versions, including Java 8, are typically installed in:
/Library/Java/JavaVirtualMachines/
This difference matters because:
/System/Libraryis reserved for software managed by Apple./Libraryis for software installed for the whole machine by users or third-party installers.- Oracle's Java installer correctly uses
/Library, not/System/Library.
So the location itself is usually not the problem.
The real concept behind this question is how macOS discovers installed JDKs and how tools choose which Java version to use.
On macOS, the command:
/ usr/libexec/java_home
normally checks installed JDK bundles and returns the best matching Java home path. Developers often use it to set JAVA_HOME, for example:
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
If does not detect a JDK, common causes include:
Mental Model
Think of macOS Java setup like a library building:
/System/Libraryis the staff-only section managed by Apple./Libraryis the public installed-software section where third-party packages go.java_homeis the catalog desk that tells programs where a matching Java version lives.JAVA_HOMEis the note you hand to your tools saying, "Use this Java installation."
So even if Java 8 is physically in the building, your tools still need the catalog desk or your environment variables to point to the right shelf.
Syntax and Examples
The most common commands for checking and configuring Java on macOS are:
/usr/libexec/java_home -V
java -version
javac -version
To ask for a specific version:
/usr/libexec/java_home -v 1.8
To temporarily set Java 8 in your current shell:
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
export PATH="$JAVA_HOME/bin:$PATH"
Example:
$ /usr/libexec/java_home -V
Matching Java Virtual Machines (2):
1.8.0_202, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home
1.6.0_65-b14-468, x86_64: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
$ export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
$ java -version
java version "1.8.0_202"
What this does:
java_home -Vlists installed JDKs that macOS recognizes.java_home -v 1.8returns the path for Java 8.JAVA_HOMEtells Java-based tools which JDK to use.- updating
PATHmakes the shell use that JDK's and commands first.
Step by Step Execution
Consider this shell session:
/usr/libexec/java_home -V
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
export PATH="$JAVA_HOME/bin:$PATH"
java -version
javac -version
Step by step:
-
/usr/libexec/java_home -V- macOS scans known Java bundle locations.
- It lists every JDK it can identify.
- If Java 8 is missing here, the OS is not recognizing that installation properly.
-
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)- The shell runs
java_home -v 1.8. - That command returns a path such as:
/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home JAVA_HOMEis set to that path.
- The shell runs
-
export PATH="$JAVA_HOME/bin:$PATH"- The shell puts Java 8's
bindirectory at the front ofPATH. - Now when you type
javaor , the shell finds the Java 8 executables first.
- The shell puts Java 8's
Real World Use Cases
This concept shows up in many practical situations:
- Running JavaFX apps: JavaFX versions often require a specific JDK.
- Building Maven or Gradle projects: the build may fail if the wrong Java version is active.
- Working on legacy systems: one project may need Java 8 while another needs Java 17.
- Using IntelliJ or Eclipse: the IDE may have a different JDK than your terminal.
- CI and automation scripts: deployment scripts often set
JAVA_HOMEexplicitly. - Command-line tools: Android, build tools, and application servers often depend on Java environment variables.
Example scenario:
A developer has:
- an old enterprise app that requires Java 8
- a newer service that uses Java 17
They use JAVA_HOME and version-specific paths so each project builds with the correct JDK instead of whichever one happens to come first in PATH.
Real Codebase Usage
In real projects, developers usually do not rely only on whatever java happens to resolve to.
Common patterns include:
- Explicit
JAVA_HOMEsetup in shell startup files such as~/.zshrcor~/.bash_profile - Project-specific SDK selection in IntelliJ IDEA
- Build-tool configuration in Gradle or Maven
- Validation scripts that check the Java version before building
- Early failure when the wrong JDK is active
Example of a shell guard in a build script:
if ! java -version 2>&1 | grep '1.8' > /dev/null; then
echo "Java 8 is required for this project."
exit 1
fi
Example of a safer pattern using JAVA_HOME:
if [ -z "$JAVA_HOME" ]; then
echo "JAVA_HOME is not set"
exit 1
fi
"$JAVA_HOME/bin/java" -version
Common Mistakes
Here are common mistakes beginners make when setting up Java on macOS.
1. Installing the JRE instead of the JDK
The JRE can run Java programs, but it does not include javac for compiling code.
Broken expectation:
java -version
javac -version
If java works but javac does not, you may have installed only a runtime.
How to avoid it:
- Install a full JDK, not just a JRE.
- Check both
java -versionandjavac -version.
2. Manually editing system folders or symlinking into /System/Library
/System/Library is not where third-party Java should be installed.
How to avoid it:
- Do not move the JDK into Apple-managed paths.
- Use the installed path under
/Library/Java/JavaVirtualMachines/.
3. Assuming the terminal and IntelliJ use the same Java
They often do not.
How to avoid it:
- Check Java in the terminal with
java -version.
Comparisons
| Concept | Purpose | Typical macOS Location | Notes |
|---|---|---|---|
| JDK | Development kit for compiling and running Java | /Library/Java/JavaVirtualMachines/.../Contents/Home | Includes javac and developer tools |
| JRE | Runtime only | Varies | Can run apps but cannot compile source code |
/System/Library | Apple-managed system software | System path | Not for normal third-party JDK installation |
/Library | Machine-wide third-party software | Standard user-installed path | Correct location for Oracle and other JDKs |
java |
Cheat Sheet
# List all JDKs macOS can find
/usr/libexec/java_home -V
# Get the path for Java 8
/usr/libexec/java_home -v 1.8
# Check runtime version
java -version
# Check compiler version
javac -version
# Set Java 8 for current shell session
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
export PATH="$JAVA_HOME/bin:$PATH"
Key rules:
- Java 8 on macOS is normally installed under
/Library/Java/JavaVirtualMachines/ - Do not move it into
/System/Library JAVA_HOMEshould usually point to.../Contents/Homejava -versionchecks the runtime currently usedjavac -versionchecks the compiler- IntelliJ SDK settings are separate from terminal settings
If Java 8 is not detected:
- confirm you installed a JDK, not just a runtime
- reinstall the JDK from a reliable source
- check
/Library/Java/JavaVirtualMachines/ - run
/usr/libexec/java_home -V - configure IntelliJ manually if needed
FAQ
Why is Java 8 installed in /Library instead of /System/Library on Mac?
/System/Library is reserved for Apple-managed software. Third-party JDKs such as Oracle Java are normally installed in /Library.
Why does java_home not find my Java 8 installation?
Usually because the JDK was not registered correctly, the installation is incomplete, or the installed package is outdated or incompatible with the OS.
What is the correct JAVA_HOME for a macOS JDK?
It is usually the Contents/Home directory inside the .jdk bundle, for example:
/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home
Is java -version enough to verify Java setup?
Not always. Also check javac -version if you plan to compile code, because a runtime-only install may not include the compiler.
Why does IntelliJ still show the wrong Java version?
IntelliJ can use a separately configured Project SDK. You may need to update the SDK in the project settings even if the terminal uses Java 8.
Should I create symlinks to make Java appear under old system folders?
Mini Project
Description
Create a small macOS shell setup for a Java 8 project. This project helps you verify whether Java 8 is installed correctly, set JAVA_HOME, update PATH, and confirm that both the runtime and compiler use the expected version. This reflects a real development workflow when preparing a machine for JavaFX or legacy Java applications.
Goal
Build a repeatable terminal setup that selects Java 8 and verifies that your shell is ready to compile and run Java 8 programs.
Requirements
- Check which Java versions macOS can detect.
- Set
JAVA_HOMEto Java 8 for the current shell session. - Update
PATHso the Java 8 binaries are used first. - Verify both
javaandjavacreport version 1.8. - Print the final
JAVA_HOMEpath so it is easy to confirm the active JDK.
Keep learning
Related questions
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Choosing a @NotNull Annotation in Java: Validation vs Static Analysis
Learn how Java @NotNull annotations differ, when to use each one, and how to choose between validation, IDE hints, and static analysis tools.
Convert a Java Stack Trace to a String
Learn how to convert a Java exception stack trace to a string using StringWriter and PrintWriter, with examples and common mistakes.