Legacy Oracle Java sits on 15 to 35 percent of the devices buyers believe are clean, and registry-based discovery finds almost none of it
In Redress engagements, filesystem-level scanning turned up Oracle JRE and JDK binaries on 15 to 35 percent of endpoints that SCCM, Intune, and installed-programs inventories reported as Java-free. Because the Universal Subscription bills on employee count rather than install count, a single missed private JRE inside a third-party desktop app can trigger a $504,000 per year subscription at a 4,000-employee company. Detection is not about the number you find, it is about whether Oracle finds one you missed.
Prepared by Redress Compliance · August 30, 2026 · Oracle Java advisory. Discovery and audit-defense engagements, 2024 to 2026.
Executive summary
The gap between what your inventory tool reports and what a filesystem scan finds runs 15 to 35 percent of devices in our engagements.
Registry keys and installed-programs lists miss private JREs bundled inside third-party desktop applications, unzipped JDK directories dropped by developers, and container images built on Oracle base layers.
The java.vendor property returns "Oracle Corporation" on OpenJDK builds, so the single most common detection signature is wrong in both directions.
AdoptOpenJDK 8u172 reported java.vendor, java.vm.vendor, java.specification.vendor and java.vm.specification.vendor all as Oracle Corporation, and Oracle's own LMS scripts have been observed flagging OpenJDK as Oracle JDK.
Your install count does not set your bill, your payroll does, which means one confirmed Oracle install at a 12,000-employee company costs $1,188,000 a year at list.
The Universal Subscription runs seven published bands from $15.00 down to $5.25 per employee per month, and the same figure applies whether you run four Oracle installs or four thousand.
The October 2026 Critical Patch Update moves JDK 21 from NFTC to the OTN license, converting a compliant estate into a paid one through routine patching. Versions 21 through 24 stay free under NFTC only through September 2026, and JDK 17 already crossed that line at 17.0.13 in September 2024.
How Oracle Java discovery actually works, and where each method breaks
Java discovery is not one scan, it is four distinct evidence layers, and each one fails in a way the others cannot cover. The first layer is registry and installed-programs inventory: SCCM, Intune, Add/Remove Programs, and the Windows uninstall keys.
This layer only sees Java that arrived through an MSI or an installer that registered itself. The second layer is a filesystem binary scan: walk the disk looking for java, java.exe, javac, rt.jar, and release, regardless of whether anything ever told the registry.
The third is runtime property interrogation: run java -version or read the system properties on each binary you found. The fourth is package and bundle metadata: RPM and DEB queries on Linux, Info.plist on macOS, and container image manifests.
Oracle's own LMS Collection Tool is essentially layers one, two, and three stitched together.
It searches the common paths (/usr/java, /opt/java, Program Files\Java), reads Windows registry entries, executes java -version against every instance it finds to capture version, update level, and vendor string, counts distinct binaries.
And probes for commercial-feature artifacts such as Java Mission Control and Flight Recorder.
Note what that description does not include: it does not reconcile ten directories on one host back to one host, and it does not verify that a vendor string is telling the truth.
| Detection layer | What it actually covers | False-positive risk | The install class it cannot see |
|---|---|---|---|
| Registry / installed-programs (SCCM, Intune, ARP) | MSI-installed Oracle JRE and JDK on Windows endpoints only | Low, but stale uninstall keys survive removal | Private JREs bundled inside third-party apps, ZIP/tar extractions, anything on Linux, macOS, or in a container |
| Filesystem binary scan | Every java/javac binary on mounted disk regardless of installer | Moderate: counts each version directory as a separate install | Container image layers not running at scan time, network shares, offline VMs, images in the golden template library |
| Runtime property interrogation (java -version, system properties) | Version, update level, and self-reported vendor for each binary found | High: OpenJDK builds have returned "Oracle Corporation" for java.vendor | Anything the scan did not already locate; it is a classifier, not a finder |
| Package / bundle metadata (RPM, DEB, Info.plist, image manifests) | Provenance where the packaging system was used | Low, and it is the most defensible evidence you can produce | Manually extracted archives, vendor-embedded runtimes, and hand-patched JDKs |
Read the middle two rows together and the audit dynamic becomes obvious. A filesystem scan on one application server carrying JDK 8, JDK 11, JDK 17, and three patch levels of each produces ten or more discovered instances on a single host.
Oracle's scripts have been observed counting exactly that way: ten installations from one server because the versions sit in different directories. Under the legacy processor metric that inflation drove the claim directly.
Under the Universal Subscription it does something arguably worse, it manufactures a narrative of sprawl that justifies a wider audit scope and a harder negotiating posture, even though your subscription cost is set entirely by headcount.
The practical consequence is that you must run all four layers and then reconcile them, because Oracle will run three of them and reconcile none.
Build your own inventory keyed on host identity, not on binary path, so that ten directories collapse to one server with a documented list of what sits on it.
Preserve the filesystem scan output separately from the classification output, because the moment you conflate "we found a binary" with "it is Oracle and it is licensable" you have adopted Oracle's own logical error and handed it back as an admission.
And extend the scan beyond running hosts: golden images, VM templates, container registries, and decommissioned-but-mounted volumes all carry binaries that a live-host tool will not reach but that a determined auditor will ask about.
Our internal Oracle license audit approach treats this reconciliation step, not the raw scan, as the deliverable.
Telling Oracle JDK from OpenJDK when java.vendor lies to you
The single most common evidentiary mistake buyers make is treating java.vendor as proof of provenance. It is not.
Red Hat has documented OpenJDK builds returning "Oracle Corporation" for java.vendor, and older AdoptOpenJDK 8u172 builds reported java.specification.vendor, java.vendor, java.vm.specification.vendor, and java.vm.vendor all as "Oracle Corporation." That is not an edge case.
It is the default behavior of a large installed base built from source that never rewrote the branding strings.
Oracle's LMS scripts read those same properties. So the failure runs in both directions: your OpenJDK gets classified as Oracle and billed, and in rare cases genuine Oracle installs get missed and then surface later as a credibility problem.
Neither outcome is one you want to discover during a formal review.
The signatures that actually hold up under challenge are the ones tied to build artifacts rather than runtime strings. Read the release file in the JDK root and pull IMPLEMENTOR and IMPLEMENTOR_VERSION, which carry the build organization rather than the specification vendor.
On Windows, check the Authenticode signature authority on java.exe and the installer: Oracle America signs its binaries, Azul signs Zulu, Amazon signs Corretto, and Eclipse Adoptium signs Temurin.
On macOS, read the JDK's Info.plist CFBundleIdentifier and pattern-match it; the published Jamf extension attribute greps for adoptopenjdk|amazon|apple|azul|openjdk|oracle|sap and returns a vendor classification per install.
On Linux, RPM and DEB provenance beats every property string in the runtime. Layer in the presence of commercial-feature artifacts (Mission Control, Flight Recorder configuration under a paid-feature path) as a secondary indicator, since Oracle's tooling probes for exactly those.
One further refinement matters now. Oracle's newer collection scripts split Oracle GraalVM, Oracle JDK, and Oracle OpenJDK builds into three distinct licensing statuses, and those statuses are not equivalent.
If your own evidence collapses all three into a single "Oracle" bucket, you have pre-conceded classifications you could have won on the record, particularly for Oracle-branded OpenJDK builds distributed under the GPL. Classify at the same granularity Oracle does, or finer.
Where a build is genuinely ambiguous, record the ambiguity with the file hashes and signature output attached rather than guessing, because an unresolved item you documented is a negotiating position, while an unresolved item you guessed on is a finding you can no longer challenge.
Defend an Oracle Java audit without overpaying
Oracle now audits Java SE on employee count, not installs, which can multiply the bill several times over. How to defend the notice and exit to OpenJDK.
Get the white paper →Why a perfect install count still does not tell you the price
Before January 2023, an install count was the bill. You counted named users and processors, you argued about virtualization boundaries, and the arithmetic followed the inventory. The Universal Subscription severed that link.
The metric is now Employee, defined in Oracle's own price list as all full-time, part-time, and temporary staff, plus the equivalent staff of your agents, contractors, outsourcers, and consultants supporting your internal business operations.
And explicitly not the number of people who touch the software.
Once you accept that definition, the discovery scan stops being a sizing exercise. It becomes a binary question: can you get to zero Oracle binaries, or can you not?
Work the numbers and the shape of the problem becomes obvious. A 5,000-employee company that needs Oracle Java on 40 servers pays for 5,000 employees. At the published band rate that is $630,000 a year at list, which works out to $15,750 per server.
A 4,000-employee company with 47 Oracle Java installs sits in the 3,000 to 9,999 band at $10.50 per employee per month, or $504,000 a year before discount.
Divide that by 47 and you get roughly $10,723 per install, but the division is misleading, because the marginal cost of the 47th install is exactly zero and the cost of the first is the entire $504,000. There is no volume curve inside your estate. There is a cliff at one.
That asymmetry rewrites what audit defense means. Under the old metrics you argued a number down: fewer processors, fewer named users, a different virtualization interpretation, and every concession you extracted moved the invoice proportionally.
Under the employee metric, arguing a count from 47 to 12 moves nothing. The only argument that pays is the one that removes the last unit. This is uncomfortable for teams trained on Oracle database defense, where the reflex is to negotiate the schedule.
Here the schedule is irrelevant, and the entire value of a discovery program sits in whether it can support a credible claim of zero commercial Oracle Java exposure.
So the defensible positions narrow to three, and every discovered binary needs to be pushed into one of them. First, it is not Oracle.
Given that OpenJDK builds can report java.vendor as "Oracle Corporation," and that older Adoptium builds returned Oracle in all four vendor properties, this argument requires filesystem and package-level evidence, not a property dump.
Second, it is not commercial use: the binary is under a version and update level still covered by a no-fee grant, or Oracle JDK 11 and above running strictly for development under the OTN terms. Third, it is covered by legacy perpetual Java SE Advanced holdings.
Those holdings earn no credit against the subscription price, and buyers who expect a trade-in will be disappointed, but they do provide genuine audit cover and migration runway for the estate they entitle. Anything that fails all three tests is not a line item you negotiate.
It is a trigger you remove or you pay for in full.
This also explains why Oracle's collection scripts behave the way they do.
The LMS tooling walks common paths, reads registry entries, executes java -version on each instance, and counts distinct binaries, which is why a single server with several version directories can be reported as ten installations. Under a per-processor metric that inflation was worth fighting.
Under the employee metric it is theater. Oracle does not need ten; it needs one, and it needs it in production or in employee hands.
Understanding that changes how you respond to a script request and how much energy you spend disputing its output, a point developed further in our guidance on challenging Oracle audit findings.
There is exactly one place where install topology still moves real money. The employee metric carries a ceiling: you may install and run on up to 50,000 Processors, and exceeding that, exclusive of desktops and laptops, requires additional licensing. For most organizations that cap is theoretical.
For large financial services, telco, and hosting estates with dense server virtualization, it is not, and it is the one condition where knowing exactly where the JVMs live, and on how many cores, has direct commercial consequence.
In our experience buyers rarely model this before signing, and it surfaces at the first true-up when the estate has grown. Model it now, in writing, and get the counting method for processors defined in the ordering document rather than discovered later in a compliance letter.
The install classes that never appear in your inventory
The 15 to 35 percent gap Redress sees between filesystem scanning and SCCM, Intune, or installed-programs inventories is not evenly distributed. It concentrates in six install classes that share one property: nobody ran an MSI, so nothing wrote a registry uninstall key or a package manager record.
Registry-based discovery is structurally blind to all six, and no amount of tuning fixes that, because the evidence it looks for was never created.
Private JREs shipped inside third-party desktop applications are the single largest contributor. The vendor bundles a runtime into its own installation directory, the endpoint agent records only the vendor's product, and the Oracle binary sits three folders down.
The detection move is a filesystem sweep for java.exe, java, and libjvm.so across all fixed volumes, then reading release files and executable metadata rather than trusting java.vendor.
Jlink runtime images are the subtler cousin: a custom runtime assembled from an Oracle JDK carries Oracle Java inside whatever application ships it, with no version directory and no vendor branding. Look for the release file and module descriptors in the application payload.
Container base images require scanning layers in the registry, not running hosts, because the image is the artifact that propagates.
Developer laptops with unzipped tarballs leave no installer trace at all, which is why they also correlate with download-log exposure documented in what Oracle's download logs reveal about you.
Appliance and vendor-managed hosts often refuse agent installation entirely, so the move is contractual: written vendor attestation on the runtime shipped and its license basis. Build agents rebuild themselves from images, so scan the pipeline definition, not the ephemeral node.
The pattern across all six classes is that the Oracle binary arrived as a dependency of something else, so it was never a decision anyone made or recorded.
That is why remediation programs stall: teams fix the installs they can see, re-scan, and find the number barely moved, because the visible estate was never where the exposure lived.
Treat this as a scoping rule. Any discovery method that depends on an installation record covers roughly two thirds to five sixths of your true footprint, and the missing portion is exactly the portion Oracle's scripts, which execute against the filesystem, will surface.
Build your own view from the binaries outward, and start the licensing review from that number rather than from the inventory report.
What the engagement evidence shows about discovery gaps and audit claims
The pattern repeats across engagements with enough consistency that we now treat it as a planning assumption rather than a surprise.
When a client hands us an SCCM, Intune, or installed-programs export and we run a filesystem binary scan alongside it, between 15 and 35 percent of endpoints reported as Java-free carry an Oracle JRE or JDK binary. The gap is not caused by bad inventory hygiene.
It is structural: registry-based and add/remove-programs discovery only sees what an MSI wrote a key for, and private JREs bundled inside third-party desktop applications, unpacked ZIP distributions, developer toolchains, and container base images write nothing. The buyer is not careless.
The tool was never designed to answer the question Oracle is asking.
Devices reported clean by registry-based inventory that filesystem scanning found carrying Oracle JRE or JDK binaries.
Advisor-assisted Universal Subscription negotiations have landed in this range through multi-year terms, bundling, and headcount carve-outs.
Three other patterns recur often enough to plan against. First, Oracle's own collection scripts produce directory counts, not host counts. A single server with four Java versions in four paths routinely arrives in the initial finding as four installations, and we have seen ten counted on one host.
That inflation is not always corrected before the number reaches a commercial conversation.
Second, OpenJDK is regularly misclassified as Oracle JDK in first-pass findings, because java.vendor returns "Oracle Corporation" on OpenJDK and on older Adoptium builds, so the property Oracle's tooling reads cannot distinguish the licensed product from the free one.
Newer collection tools separate Oracle GraalVM, Oracle JDK, and Oracle OpenJDK builds more carefully, but the burden of proving misclassification still sits with you, and it sits there under time pressure.
Third, on the buyer side, finance teams routinely add a 22 percent support uplift to a Universal Subscription budget. That line does not exist. The employee-metric rate is all-in, so anyone modeling it is overstating the deal by roughly a fifth and negotiating against a target that was never real.
The contractual position deserves flat statement. Current Oracle audit clauses oblige you to run Oracle's data measurement tools and hand back the results. You are not obliged to accept Oracle's reading of what those results mean, and the distinction is where the money sits.
In practice, the buyers who fare best run their own filesystem scan first, know their true host count and their vendor classification before the script executes, and can rebut a directory-count claim on the day it lands rather than three weeks later.
Our internal Oracle license audit work exists precisely to compress that window. Against that preparation, advisor-assisted negotiation has typically landed 20 to 40 percent below list through multi-year commitments, bundling, and headcount definition carve-outs.
Against an unprepared buyer holding an inflated Oracle number, the discount is applied to a base that should have been smaller, and the saving is illusory.
Legacy perpetual Java SE Advanced holdings, where they still exist, are worth documenting now: they earn no credit against subscription price, but they are genuine audit cover for historical deployments and buy migration runway.
Read the audit finding as an opening claim, not an invoice, and treat challenging the methodology as the first commercial move rather than a last resort.
- Percentile standing for your exact deal size and industry, from real closed transactions
- Scenario simulation before the call: test alternative terms and see the financial impact of each
- A negotiation playbook, talking points, and a two page executive brief on day one
Your first five moves
- Run a filesystem binary scan before any contact with Oracle, searching for java, java.exe, and release files across all mount points and Program Files paths rather than trusting registry inventory, on the working assumption that 15 to 35 percent of your "clean" endpoints will return a hit.
- Classify every hit by the release file signature, not java.vendor, because OpenJDK and older Adoptium builds report "Oracle Corporation" in that property, and misclassified OpenJDK is the single most common inflation in a first-pass Oracle finding.
- Freeze patch pipelines on JDK 21 through 24 now, ahead of the September 2026 NFTC expiry, since updates from the October 2026 Critical Patch Update onward move to OTN terms and a routine automated patch will convert free installs into licensable ones with no purchase order raised.
- Locate and document every legacy perpetual Java SE Advanced entitlement, with contract numbers and effective dates, treating them as audit cover for historical deployment rather than as credit against subscription price, which they do not provide.
- Pre-build the counter-methodology you will hand back when Oracle's LMS output arrives, specifically a host-level reconciliation that collapses multi-directory installs into single hosts and a vendor classification table, so a ten-installation claim on one server is corrected in days rather than weeks.
The five moves are ordered deliberately, and the order matters more than any individual action. Everything after move one depends on you owning the dataset first.
Once Oracle's collection script runs and produces the first number, that number anchors the entire commercial conversation, and every subsequent correction you make is framed as a buyer disputing an audit finding rather than as a vendor misreading a known estate.
The 20 to 40 percent below list outcomes we see are almost always achieved by buyers who walked in already knowing their host count, their vendor split, and their employee-metric exposure.
One budget correction belongs alongside these five.
Because the subscription bills on total employee headcount including contractors, agents, and outsourcer staff supporting internal operations.
Your remediation target is not "reduce installs to zero for a discount." It is either full removal of Oracle binaries across the estate or acceptance of an employee-count bill that a 47-install footprint and a 4,000-person payroll turns into $504,000 a year at the published $10.50 band.
Partial cleanup buys nothing commercially, though it does reduce audit surface. Decide which outcome you are funding before the scan results reach your CFO, and keep the 22 percent phantom uplift out of the model entirely.
If the answer is full removal, a structured Java licensing review should set the migration deadline against the October 2026 patch cliff, not against your renewal date, because the patch pipeline moves first.
Frequently asked questions
How do I find every Oracle Java install on my network?
Registry and installed-programs inventory alone will miss 15 to 35 percent of them based on our engagement data.
Run a filesystem-level scan for the actual runtime binaries (java, java.exe, libjvm.so, the release file) across all mount points and user directories, not just /usr/java, /opt/java and Program Files\\Java.
Extend the same scan to container images, build agents, and developer laptops, which sit outside most endpoint management scope.
How can I tell if an install is Oracle JDK or OpenJDK?
Do not rely on java.vendor. OpenJDK builds have been documented returning "Oracle Corporation" for java.vendor, java.vm.vendor, and both specification vendor properties.
Read the release file's IMPLEMENTOR and IMPLEMENTOR_VERSION fields, check the Windows binary's digital signature authority, and on macOS read the CFBundleIdentifier from Info.plist and pattern-match the vendor string.
Does finding fewer Oracle Java installs reduce what I pay?
No. The Java SE Universal Subscription is priced on employee count, not install count. A 12,000-employee enterprise pays $1,188,000 a year at list whether it runs four Oracle installs or four thousand.
Discovery matters because reaching zero qualifying installs is the only outcome that changes the number, not because a lower count earns a discount.
What happens to Oracle JDK 21 after October 2026?
JDK 21 updates through and including September 2026 remain under the No-Fee Terms and Conditions. Updates beginning with the October 2026 Critical Patch Update move to the Java SE OTN license, the same license governing Java 8, 11 and 17.
The change does not retroactively make an existing deployment unlicensed, it stops the free flow of patches, so an unmanaged patch pipeline is what creates the liability.
Am I obligated to run Oracle's LMS Collection Tool during an audit?
Current Oracle audit clauses typically require customers to run Oracle's data measurement tools and provide the results, so in a formal audit you should expect the demand and should check your specific contract language before responding. Running the tool does not mean accepting its output.
The tool has been observed counting multiple JDK directories on a single server as multiple installations and classifying OpenJDK as Oracle JDK.
Do legacy perpetual Java SE Advanced licenses reduce the subscription cost?
They earn no credit against the Universal Subscription price. What they do provide is audit cover for the deployments they legitimately entitle and runway for a migration off Oracle builds.
Document them precisely, including quantity and metric, before any audit correspondence begins, because they are frequently omitted from Oracle's own entitlement picture.
Does a jlink custom runtime avoid Oracle Java licensing?
No. A jlink image assembled from an Oracle JDK carries Oracle Java code inside whatever application ships it. The license status follows the source JDK, not the packaging.
If your build pipeline pulls an Oracle JDK as its jlink source, every artifact downstream inherits that status, and filesystem scanning of production hosts will not always flag it unless you also inspect build configurations.