Short answer
List every Java home on the machine (package manager, standard install folders, PATH, SDK managers, running processes), then read each one's release file and java -version output. A build that reports Java(TM) SE Runtime Environment or has BUILD_TYPE="commercial" is Oracle JDK; one that reports OpenJDK Runtime Environment is an OpenJDK build. IMPLEMENTOR="Oracle Corporation" alone doesn't tell you, because Oracle's free OpenJDK builds use it too.
Before you can say which of your Java installs fall under which Oracle license, you need the list. This guide gives copy-paste commands for Linux, macOS and Windows, then shows how to tell an Oracle JDK build from an OpenJDK build without guessing. Everything here is read-only.
| Strongest local signal | java -version prints Java(TM) SE Runtime Environment (Oracle JDK/JRE) or OpenJDK Runtime Environment (OpenJDK build)5 |
|---|---|
| release file keys | JAVA_VERSION, JAVA_RUNTIME_VERSION, IMPLEMENTOR; Oracle's commercial builds are also observed with BUILD_TYPE="commercial" (not documented by Oracle)4 |
| Not enough on its own | IMPLEMENTOR="Oracle Corporation", and the rpm/dpkg vendor field |
| Oracle default paths | Linux /usr/lib/jvm/jdk-21-oracle-x641; macOS /Library/Java/JavaVirtualMachines/jdk-21.jdk2; Windows C:\Program Files\Java\jdk-213 |
| Often missed | SDK managers, IDE-downloaded JDKs, bundled runtimes, container images, CI workflows, auto-updaters |
Linux
Step 1: list every Java home
Start with the package manager, then look at the file system, because tarball installs never show up in rpm or dpkg. Oracle's own RPM and DEB packages install to /usr/lib/jvm/jdk-<version>-oracle-<arch>, and the RPM adds a /usr/java/jdk-21 symlink.1
# 1. Packages (names, versions, vendors) $ rpm -qa --qf '%{NAME} %{VERSION}-%{RELEASE} %{VENDOR}\n' | grep -i -E 'jdk|jre|java' $ dpkg-query -W -f='${Package} ${Version} ${Maintainer}\n' | grep -i -E 'jdk|jre|java' # 2. Registered alternatives $ update-alternatives --list java 2>/dev/null || alternatives --display java # 3. Every bin/java on local file systems $ sudo find / -xdev -type f -path '*/bin/java' 2>/dev/null # 4. What is running right now $ for p in $(pgrep -x java); do sudo readlink -f /proc/$p/exe; done | sort -u
-xdev keeps find on the root file system; repeat it for other local mounts such as /opt or /srv if they are separate. Also look in each user's ~/.sdkman/candidates/java, ~/.asdf/installs/java, ~/.jdks (IntelliJ IDEA) and ~/.gradle/jdks.
Step 2: read the release file and ask the JVM
Every modern JDK has a plain-text release file in its home directory. JEP 322 defines keys such as JAVA_VERSION and JAVA_VERSION_DATE.4 Pair it with the runtime name the JVM reports.
$ for home in /usr/lib/jvm/* /usr/java/* /opt/*; do
[ -f "$home/release" ] || continue
echo "== $home"
grep -E '^(JAVA_VERSION|JAVA_RUNTIME_VERSION|IMPLEMENTOR|BUILD_TYPE)=' "$home/release"
"$home/bin/java" -XshowSettings:properties -version 2>&1 | grep -E 'java\.runtime\.name|java\.vendor ='
done
Oracle's JDK 11 release notes explain the naming difference: Oracle JDK says java and includes the LTS identifier, while OpenJDK builds produced by Oracle say OpenJDK.5 OpenJDK's default build branding is OpenJDK Runtime Environment with no company name,6 so a non-Oracle vendor string plus that runtime name is an OpenJDK build.
macOS
Oracle's macOS installer puts the JDK in /Library/Java/JavaVirtualMachines/jdk-<feature>.jdk, and /usr/libexec/java_home lists what the system knows about.2 The older Oracle Java 8 JRE lives in the browser plug-in folder and installs a LaunchAgent for Java Update.
$ /usr/libexec/java_home -V 2>&1 $ ls -d /Library/Java/JavaVirtualMachines/* ~/Library/Java/JavaVirtualMachines/* 2>/dev/null $ for home in /Library/Java/JavaVirtualMachines/*/Contents/Home; do echo "== $home"; grep -E '^(JAVA_VERSION|IMPLEMENTOR|BUILD_TYPE)=' "$home/release"; done # Oracle Java 8 JRE (browser plug-in location) and its updater $ ls -d '/Library/Internet Plug-Ins/JavaAppletPlugin.plugin' /Library/LaunchAgents/com.oracle.java.Java-Updater.plist 2>/dev/null $ brew list --cask 2>/dev/null | grep -i -E 'jdk|temurin|zulu|corretto|liberica'
Don't remove anything from /usr/bin: Oracle's guide warns that those tools are part of macOS and come back with system updates.2
Windows
Oracle's Windows installer defaults to C:\Program Files\Java\jdk-21 and registers an uninstall entry you can find in the registry.3 Run these in 64-bit PowerShell; a 32-bit session sees a different registry view.
# Java homes registered by installers (64-bit and 32-bit views) PS> Get-ChildItem 'HKLM:\SOFTWARE\JavaSoft', 'HKLM:\SOFTWARE\WOW6432Node\JavaSoft' -Recurse -ErrorAction SilentlyContinue | Get-ItemProperty | Where-Object JavaHome | Select-Object PSChildName, JavaHome # Installed programs with a Java, JDK or JRE name PS> Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*', 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' -ErrorAction SilentlyContinue | Where-Object DisplayName -Match 'Java|JDK|JRE' | Select-Object DisplayName, DisplayVersion, Publisher, InstallLocation # release file of every folder under Program Files\Java PS> Get-ChildItem 'C:\Program Files\Java', 'C:\Program Files (x86)\Java' -Directory -ErrorAction SilentlyContinue | ForEach-Object { $r = Join-Path $_.FullName 'release'; if (Test-Path $r) { "== $($_.FullName)"; (Select-String -Path $r -Pattern '^(JAVA_VERSION|IMPLEMENTOR|BUILD_TYPE)=').Line } } # java.exe on PATH, running Java processes, and the Java Update Scheduler PS> where.exe java PS> Get-Process java, javaw, jusched -ErrorAction SilentlyContinue | Select-Object Name, Path -Unique
If jusched is running, the Java Update Scheduler is active. Java Update periodically checks for new versions and asks to install them,7 and every Oracle Java 8 update since 8u211 is under the OTN license.8 On a business machine, clicking Update installs a build that needs a subscription for commercial use.
Containers, images and CI
Host scans miss the Java inside images and pipelines. Search your repositories for Oracle's registry and download URLs, and check running containers directly. The Oracle container registry's java/jdk repository carries images for every JDK release, so a floating tag follows the newest update of that line.9
$ grep -rn -E 'container-registry\.oracle\.com/java|download\.oracle\.com/java' --include='Dockerfile*' --include='*.yml' --include='*.yaml' --include='*.sh' . $ docker ps --format '{{.ID}} {{.Image}}' | while read -r id image; do echo "== $image"; docker exec "$id" java -version 2>&1 | head -2; done
For GitHub Actions, look for distribution: oracle in workflow files; the setup-java guide covers what each version setting downloads.
Reading the results
| What you see | Most likely | Next step |
|---|---|---|
Java(TM) SE Runtime Environment, or BUILD_TYPE="commercial" | Oracle JDK or JRE | Check the version against the OTN and NFTC boundaries |
OpenJDK Runtime Environment with a vendor such as Eclipse Adoptium, Amazon.com Inc., Azul Systems or Microsoft | OpenJDK build | Free to use; keep it patched |
OpenJDK Runtime Environment with IMPLEMENTOR="Oracle Corporation" | Oracle's GPL OpenJDK build from jdk.java.net10 | Free, but Oracle only updates each release for about six months |
| Oracle signal and OpenJDK signal together, GraalVM, or no release file | Unclear | Mark it needs review; don't guess |
Version decides the license
Finding Oracle JDK is half the job. Oracle JDK 17.0.12 is under NFTC while 17.0.13 is under OTN, so record the full version string for every install. The JDK 21 guide and the glossary list the boundaries.
Doing this on more than a handful of hosts
Loop over hosts with SSH or your configuration management tool and collect structured output, not screenshots of terminal text. Keep one file per host with the hostname, the date, each Java home's path, the release keys and the runtime name. That file is the evidence you will want if anyone asks later how the inventory was produced.
How RuntimeClear helps
The free RuntimeClear scanner runs these same checks on Linux, macOS and Windows, including SDK managers, IDE JDKs, running processes and, with --repo, Dockerfiles and CI files. It is read-only, makes no network calls and writes one JSON file per host. Drop the files into the report tool to see counts by status for free; the paid report adds each finding with its license and the commands to replace it.
Sources
- Oracle JDK 21 installation guide: Linux Checked 2026-09-11.
- Oracle JDK 21 installation guide: macOS Checked 2026-09-11.
- Oracle JDK 21 installation guide: Windows Checked 2026-09-11.
- JEP 322: Time-Based Release Versioning (release file keys) Checked 2026-09-11.
- JDK 11 release notes: Oracle JDK vs OpenJDK builds Checked 2026-09-11.
- OpenJDK 21u build branding defaults (branding.conf) Checked 2026-09-11.
- java.com: What is Java Update and how do I change the update schedule? Checked 2026-09-11.
- java.com: Oracle Java SE license notice Checked 2026-09-11.
- oracle/docker-images: OracleJava README (container-registry.oracle.com images) Checked 2026-09-11.
- jdk.java.net: Oracle's OpenJDK builds Checked 2026-09-11.