[{"data":1,"prerenderedAt":1673},["ShallowReactive",2],{"services":3,"article-\u002Farticles\u002Fjvm-patch-failure-modes":776,"author-patchmageddon-team":1219,"related-\u002Farticles\u002Fjvm-patch-failure-modes":1235,"article-surround-\u002Farticles\u002Fjvm-patch-failure-modes":1666},[4,257,383,502,603,693],{"id":5,"title":6,"body":7,"category":238,"description":239,"engagement":240,"extension":241,"headline":242,"icon":243,"meta":244,"navigation":245,"order":246,"outcomes":247,"path":253,"seo":254,"stem":255,"__hash__":256},"services\u002Fservices\u002Fjvm-discovery.md","JVM Discovery & Estate Assessment",{"type":8,"value":9,"toc":228},"minimark",[10,15,24,27,31,34,79,83,93,125,129,206,210],[11,12,14],"h2",{"id":13},"the-problem","The problem",[16,17,18,19,23],"p",{},"Most enterprises can't produce an accurate, current list of the Java runtimes they run. The CMDB records some. Config management records others. The rest are ",[20,21,22],"strong",{},"shadow JVMs",": runtimes bundled inside vendor products, application servers, CI\u002FCD agents, monitoring tools, desktop software and container images that nobody thinks of as \"Java\".",[16,25,26],{},"Shadow JVMs are the ones that miss every patch cycle. For Oracle Java, they are also the installs that can put your entire headcount in scope for a subscription.",[11,28,30],{"id":29},"what-we-find","What we find",[16,32,33],{},"For every JVM across dev, staging and production we capture:",[35,36,37,44,50,56,62,68],"ul",{},[38,39,40,43],"li",{},[20,41,42],{},"Version, vendor and patch level",": Oracle JDK, Eclipse Temurin, Amazon Corretto, Azul Zulu, Red Hat, Microsoft, IBM Semeru and others",[38,45,46,49],{},[20,47,48],{},"Where it is embedded",": standalone apps, Tomcat, WebLogic, WebSphere, JBoss\u002FWildFly, vendor products, containers",[38,51,52,55],{},[20,53,54],{},"CVE exposure",", mapped to each version and scored so the worst exposure rises to the top",[38,57,58,61],{},[20,59,60],{},"Installed agents",": APM, security and profiling agents, which cause many patch failures",[38,63,64,67],{},[20,65,66],{},"Ownership",": who actually runs each application. This is often the hardest part to get right.",[38,69,70,73,74],{},[20,71,72],{},"Criticality signals"," that feed ",[75,76,78],"a",{"href":77},"\u002Fapproach#classification","application classification",[11,80,82],{"id":81},"how-we-do-it","How we do it",[84,85,86],"note",{},[16,87,88,89,92],{},"Discovery is ",[20,90,91],{},"read-only",". Nothing is patched, restarted or deployed, so the engagement doesn't need change-control approval, and the access we ask for is kept to a minimum.",[35,94,95,101,107,113,119],{},[38,96,97,100],{},[20,98,99],{},"Agentless scanning"," over SSH and WinRM (process listings and filesystem inspection) where possible",[38,102,103,106],{},[20,104,105],{},"Reconciliation against your CMDB and config management"," (Ansible, Puppet, Chef). The drift between what is recorded and what is running is a finding in its own right.",[38,108,109,112],{},[20,110,111],{},"Cloud provider APIs"," (AWS, Azure, GCP) for instance and container metadata",[38,114,115,118],{},[20,116,117],{},"Container image and artifact repository scanning"," (registries, Nexus, Artifactory) to catch JVMs before they are even running",[38,120,121,124],{},[20,122,123],{},"Reuse of the scanners you already own",". Tenable, Qualys, Snyk and JFrog Xray already collect useful data. We add the JVM-specific interpretation and a remediation plan; we don't sell you another scanner.",[11,126,128],{"id":127},"three-ways-to-engage","Three ways to engage",[130,131,132,151],"table",{},[133,134,135],"thead",{},[136,137,138,142,145,148],"tr",{},[139,140,141],"th",{},"Package",[139,143,144],{},"Scope",[139,146,147],{},"Turnaround",[139,149,150],{},"Purpose",[152,153,154,171,187],"tbody",{},[136,155,156,162,165,168],{},[157,158,159],"td",{},[20,160,161],{},"Quick Scan",[157,163,164],{},"One business unit or subset of the estate",[157,166,167],{},"Days",[157,169,170],{},"Prove what a full assessment will find",[136,172,173,178,181,184],{},[157,174,175],{},[20,176,177],{},"Full Estate Assessment",[157,179,180],{},"The whole estate",[157,182,183],{},"2–4 weeks",[157,185,186],{},"Complete inventory, risk report and remediation plan",[136,188,189,197,200,203],{},[157,190,191],{},[20,192,193],{},[75,194,196],{"href":195},"\u002Fservices\u002Fdrift-monitoring","Continuous Drift Monitoring",[157,198,199],{},"Ongoing",[157,201,202],{},"Subscription",[157,204,205],{},"Keep the inventory, risk and license picture current",[11,207,209],{"id":208},"what-you-walk-away-with","What you walk away with",[16,211,212,213,217,218,222,223,227],{},"The executive summary puts the findings in business terms: unbudgeted license exposure, days of exposure on unpatched critical CVEs, and the percentage of the estate on end-of-life versions. It ends with a direct recommendation of which applications belong in ",[75,214,216],{"href":215},"\u002Fservices\u002Frapid-patch","Rapid Patch",", which need ",[75,219,221],{"href":220},"\u002Fservices\u002Fcritical-patch-assurance","Critical Patch Assurance",", and which Oracle installs to ",[75,224,226],{"href":225},"\u002Fservices\u002Fopenjdk-migration","migrate or keep",".",{"title":229,"searchDepth":230,"depth":231,"links":232},"",2,3,[233,234,235,236,237],{"id":13,"depth":230,"text":14},{"id":29,"depth":230,"text":30},{"id":81,"depth":230,"text":82},{"id":127,"depth":230,"text":128},{"id":208,"depth":230,"text":209},"jvm-discovery","Find every JVM in your estate, including the ones bundled inside vendor products and containers, and turn the findings into a prioritized, costed remediation plan.","Read-only and fixed-price. A Quick Scan of one business unit takes days; a Full Estate Assessment takes two to four weeks. Nothing changes in production, so no CAB approval is needed.","md","Start here","i-lucide-radar",{},true,1,[248,249,250,251,252],"A complete inventory of every JVM, with version, vendor, patch level and location","CVE exposure scored per JVM, not a raw vulnerability count","Oracle Java license exposure quantified in dollars","Owners mapped for each application","An executive summary with a prioritized remediation plan","\u002Fservices\u002Fjvm-discovery",{"title":6,"description":239},"services\u002Fjvm-discovery","xwCt4w5iuENInyc5KpzKLmV4sk8GzNe5e1H4Q9b7mV8",{"id":258,"title":259,"body":260,"category":368,"description":369,"engagement":370,"extension":241,"headline":371,"icon":372,"meta":373,"navigation":245,"order":230,"outcomes":374,"path":225,"seo":380,"stem":381,"__hash__":382},"services\u002Fservices\u002Fopenjdk-migration.md","Oracle Java Licensing & OpenJDK Migration",{"type":8,"value":261,"toc":358},[262,266,273,279,287,293,297,302,309,313,316,320,323,327,335,339],[11,263,265],{"id":264},"why-this-is-urgent","Why this is urgent",[16,267,268,269,272],{},"Since January 2023, Oracle has sold Java SE through the ",[20,270,271],{},"Java SE Universal Subscription",", which is priced per employee rather than per installation. The count covers full-time, part-time and temporary staff, plus contractors who support internal operations, however few machines actually run Oracle Java.",[16,274,275,276,227],{},"So a handful of forgotten Oracle JDK installs can put your whole headcount in scope. For example, an organization of 5,000 employees running Oracle Java on 40 servers can face a list-price bill of around ",[20,277,278],{},"$630,000 a year",[16,280,281,282,286],{},"The free window is closing too. Oracle's No-Fee Terms and Conditions (NFTC) cover each LTS release only until one year after the next LTS ships. For Oracle JDK 21, that window ",[75,283,285],{"href":284},"\u002Farticles\u002Fjava-21-nftc-free-period-ended","closed on September 16, 2026",". Continuing to patch it now requires a paid subscription.",[288,289,290],"warning",{},[16,291,292],{},"We are not lawyers, and nothing here is legal advice. Licensing terms and prices change; check them against Oracle's current price list and your own agreements. Where a formal licensing position is needed, we work alongside independent licensing specialists.",[11,294,296],{"id":295},"what-we-do","What we do",[298,299,301],"h3",{"id":300},"_1-quantify-the-exposure","1. Quantify the exposure",[16,303,304,305,308],{},"Using the ",[75,306,307],{"href":253},"discovery inventory",", we identify every Oracle JDK and JRE, how it got there, and whether it is covered by another product's license. Then we put a number on what it costs you.",[298,310,312],{"id":311},"_2-decide-install-by-install","2. Decide, install by install",[16,314,315],{},"Most Oracle installs have no reason to be Oracle. A few do: vendor certification requirements or specific support needs. We make that call explicitly for each install instead of by default.",[298,317,319],{"id":318},"_3-migrate","3. Migrate",[16,321,322],{},"OpenJDK builds from Eclipse Adoptium (Temurin), Amazon (Corretto), Azul (Zulu), Red Hat and Microsoft are TCK-tested and free to use in production. For same-version swaps, migration is usually low risk, but not zero risk. We check for the known differences: truststore contents, installer paths and registry keys, fonts, and old commercial-feature flags. Then we roll out progressively.",[298,324,326],{"id":325},"_4-prove-it","4. Prove it",[16,328,329,330,334],{},"Uninstalling is not the same as re-pointing ",[331,332,333],"code",{},"JAVA_HOME",". We verify that Oracle binaries are actually gone and keep the evidence, which you will want if Oracle ever asks.",[11,336,338],{"id":337},"further-reading","Further reading",[35,340,341,346,352],{},[38,342,343],{},[75,344,345],{"href":284},"Oracle JDK 21's free update window has closed",[38,347,348],{},[75,349,351],{"href":350},"\u002Farticles\u002Foracle-java-employee-metric-explained","Oracle's employee-based Java pricing, explained",[38,353,354],{},[75,355,357],{"href":356},"\u002Farticles\u002Foracle-jdk-to-openjdk-migration-checklist","An Oracle JDK to OpenJDK migration checklist",{"title":229,"searchDepth":230,"depth":231,"links":359},[360,361,367],{"id":264,"depth":230,"text":265},{"id":295,"depth":230,"text":296,"children":362},[363,364,365,366],{"id":300,"depth":231,"text":301},{"id":311,"depth":231,"text":312},{"id":318,"depth":231,"text":319},{"id":325,"depth":231,"text":326},{"id":337,"depth":230,"text":338},"oracle-licensing","Quantify your Oracle Java SE exposure, then move every install that doesn't need Oracle onto a free, drop-in OpenJDK build, with evidence you can take to an audit or renewal.","Fixed-scope. We start from the discovery inventory, size your exposure, then migrate in waves. Low-criticality apps go first via Rapid Patch.","Often pays for itself","i-lucide-arrow-right-left",{},[375,376,377,378,379],"Your Oracle Java license exposure, in dollars, with the installs that drive it","A keep-or-migrate decision for every Oracle JDK install","Migration to Temurin, Corretto, Zulu, Red Hat or Microsoft builds of OpenJDK","Verified removal of Oracle binaries, with an evidence trail","Data to negotiate from ahead of an audit or renewal",{"title":259,"description":369},"services\u002Fopenjdk-migration","0aWf4Vd_7P0phaKwOWxq3bLjO4iX8gdRjDu_tPGAWBY",{"id":384,"title":216,"body":385,"category":488,"description":489,"engagement":490,"extension":241,"headline":491,"icon":492,"meta":493,"navigation":245,"order":231,"outcomes":494,"path":215,"seo":499,"stem":500,"__hash__":501},"services\u002Fservices\u002Frapid-patch.md",{"type":8,"value":386,"toc":482},[387,391,394,401,405,412,424,428,465,471,475],[11,388,390],{"id":389},"the-premise","The premise",[16,392,393],{},"Full regression testing before every JVM security patch is the main reason enterprise patch cycles take months. For business-critical systems that rigor is warranted. For the long tail of internal tools, batch jobs and low-traffic services it usually isn't. There it just delays the fix for a known CVE.",[16,395,396,397,400],{},"Rapid Patch ",[20,398,399],{},"does not skip testing",". It replaces pre-deployment regression testing with fast detection and fast rollback. If a bad patch is caught in minutes and reversed in minutes, running without an exhaustive test suite costs very little.",[11,402,404],{"id":403},"who-its-for","Who it's for",[16,406,407,408,411],{},"Applications that score below the critical threshold in our ",[75,409,410],{"href":77},"classification process",". This is a documented, weighted score with a named risk-acceptor, not an app owner's self-assessment. Apps near the threshold go to manual review.",[16,413,414,415,418,419,423],{},"Rapid Patch covers ",[20,416,417],{},"same-major security patches"," (for example 17.0.x to the next 17.0.x). Major version upgrades and vendor swaps are ",[75,420,422],{"href":421},"\u002Fapproach#patch-types","different engagements"," with a different risk profile.",[11,425,427],{"id":426},"how-it-works","How it works",[35,429,430,436,442,448,454],{},[38,431,432,435],{},[20,433,434],{},"Progressive rollout",": canary at 1%, then 10%, then 100%, gated on automated health checks",[38,437,438,441],{},[20,439,440],{},"Observability as the safety net",": error rates, latency, GC pause times, heap and thread behavior compared before and after the patch",[38,443,444,447],{},[20,445,446],{},"Fast, rehearsed rollback",": the previous runtime stays in place until the soak period ends, and rollback is exercised, not just written down",[38,449,450,453],{},[20,451,452],{},"Smoke tests and synthetic transactions"," for the paths that matter, in place of a full regression suite",[38,455,456,459,460,464],{},[20,457,458],{},"A pre-flight check"," for ",[75,461,463],{"href":462},"\u002Farticles\u002Fjvm-patch-failure-modes","known failure modes",": APM agents, TLS defaults, GC flags",[466,467,468],"tip",{},[16,469,470],{},"In many non-containerized estates, reliable rollback is the real gap. When that's the case we fix it first, because that step alone makes the patch cycle faster.",[11,472,474],{"id":473},"governance","Governance",[16,476,477,478],{},"Your Change Advisory Board approves the process once, as a standard change for a defined tier, instead of approving each patch. Every rollout produces evidence: which signals were checked, the results, timestamps, and who accepted the risk. ",[75,479,481],{"href":480},"\u002Farticles\u002Fcab-approval-for-faster-jvm-patching","How we get this past a CAB →",{"title":229,"searchDepth":230,"depth":231,"links":483},[484,485,486,487],{"id":389,"depth":230,"text":390},{"id":403,"depth":230,"text":404},{"id":426,"depth":230,"text":427},{"id":473,"depth":230,"text":474},"patch-management","Patch the long tail of non-business-critical Java apps in days, not quarters, by replacing full regression testing with progressive rollout, fast detection and rehearsed rollback.","Fixed-scope rollout of a patching pipeline and governance model for a defined tier of applications, followed by patch cycles run each quarter.","For non-critical apps","i-lucide-zap",{},[495,496,497,498],"Security patches applied across the tier in days after each quarterly release","Progressive rollout with automated health gates","A rollback path that has been tested, not just documented","A CAB-approved standard-change process and audit trail",{"title":216,"description":489},"services\u002Frapid-patch","qDIP1lgG0nnDOEyokq47L3LSfKbmYPHSlBnCXM3udLw",{"id":503,"title":221,"body":504,"category":588,"description":589,"engagement":590,"extension":241,"headline":591,"icon":592,"meta":593,"navigation":245,"order":594,"outcomes":595,"path":220,"seo":600,"stem":601,"__hash__":602},"services\u002Fservices\u002Fcritical-patch-assurance.md",{"type":8,"value":505,"toc":576},[506,510,517,523,527,531,534,538,541,545,548,552,555,559,562,566,569,573],[11,507,509],{"id":508},"a-different-promise","A different promise",[16,511,512,513,516],{},"For business-critical applications the value proposition flips. We aren't removing testing. We ",[20,514,515],{},"compress"," it so that each test cycle is shorter and gives you more confidence, and full rigor becomes possible on a faster cadence.",[16,518,519,520,522],{},"This is a different engagement from ",[75,521,216],{"href":215},", built on a different premise, not the same thing done more carefully.",[11,524,526],{"id":525},"whats-in-it","What's in it",[298,528,530],{"id":529},"test-impact-analysis-and-risk-based-test-selection","Test impact analysis and risk-based test selection",[16,532,533],{},"We use code coverage and change-impact analysis to find which of your existing regression tests actually exercise code paths affected by the JVM change, and run those on a compressed timeline. When the signal is ambiguous we escalate to the full suite.",[298,535,537],{"id":536},"shadow-traffic-and-dark-launch-testing","Shadow traffic and dark launch testing",[16,539,540],{},"We mirror real production traffic to a shadow instance running the patched JVM and diff its outputs against production, with no user exposure. This is the strongest \"test better, not less\" option available for critical services.",[298,542,544],{"id":543},"upgrade-readiness-assessment","Upgrade readiness assessment",[16,546,547],{},"Before any patch or upgrade, we scan for removed and deprecated API usage, known agent incompatibilities and dependency issues, and produce a risk report up front.",[298,549,551],{"id":550},"staging-and-production-parity-audits","Staging and production parity audits",[16,553,554],{},"Much critical-app patch risk comes from drift between staging and production, not from the patch itself. Closing that gap often gives you more than adding tests does.",[298,556,558],{"id":557},"canary-gates-on-business-metrics","Canary gates on business metrics",[16,560,561],{},"We go beyond latency and error rates to business invariants, such as transaction success rate, order completion and revenue per minute, and use them as automated rollback triggers.",[298,563,565],{"id":564},"patch-trains-and-war-room-support","Patch trains and war-room support",[16,567,568],{},"Scheduled, batched patch windows for critical apps, with dedicated live support during rollout, instead of ad hoc patching.",[298,570,572],{"id":571},"lts-aligned-strategy-and-vendor-coordination","LTS-aligned strategy and vendor coordination",[16,574,575],{},"Critical apps stay on designated LTS and security baselines, which keeps exposure windows short without constant churn. Where it matters, we work directly with your JVM vendor on compatibility and support commitments.",{"title":229,"searchDepth":230,"depth":231,"links":577},[578,579],{"id":508,"depth":230,"text":509},{"id":525,"depth":230,"text":526,"children":580},[581,582,583,584,585,586,587],{"id":529,"depth":231,"text":530},{"id":536,"depth":231,"text":537},{"id":543,"depth":231,"text":544},{"id":550,"depth":231,"text":551},{"id":557,"depth":231,"text":558},{"id":564,"depth":231,"text":565},{"id":571,"depth":231,"text":572},"risk-governance","For business-critical Java applications, we compress testing instead of removing it, so full rigor fits a faster patch cadence.","A higher-touch engagement for critical applications, typically starting with an upgrade-readiness assessment and continuing with scheduled patch trains.","For the apps that run the business","i-lucide-shield",{},4,[596,597,598,599],"Shorter test cycles for critical apps with the same or greater confidence","Shadow-traffic validation with no user exposure","Canary gates on business metrics, not just infrastructure metrics","Scheduled patch trains with live war-room support",{"title":221,"description":589},"services\u002Fcritical-patch-assurance","utoXA8F7946svO9yfDqjkPV5VtPJhDVhuelRoxSfZeU",{"id":604,"title":605,"body":606,"category":676,"description":677,"engagement":678,"extension":241,"headline":679,"icon":680,"meta":681,"navigation":245,"order":682,"outcomes":683,"path":689,"seo":690,"stem":691,"__hash__":692},"services\u002Fservices\u002Fthird-party-applications.md","Vendor & Third-Party Application JVMs",{"type":8,"value":607,"toc":672},[608,612,622,625,627,667],[11,609,611],{"id":610},"the-jvms-nobody-owns","The JVMs nobody owns",[16,613,614,615,618,619,227],{},"A large share of the Java in an enterprise wasn't written there. Application servers, database tooling, CI\u002FCD servers, monitoring agents, ETL tools, security appliances and desktop software often ship their ",[20,616,617],{},"own private JVM",", installed outside the package manager and invisible to anything that only checks the system ",[331,620,621],{},"java",[16,623,624],{},"These runtimes fall between two chairs. The platform team assumes the vendor patches them; the vendor assumes you'll apply their next release; the application owner assumes it's all fine. Meanwhile the bundled JVM ages.",[11,626,296],{"id":295},[35,628,629,639,645,655,661],{},[38,630,631,634,635,638],{},[20,632,633],{},"Find and attribute them."," ",[75,636,637],{"href":253},"Discovery"," surfaces bundled runtimes and ties each one to a product, version and business owner.",[38,640,641,644],{},[20,642,643],{},"Establish the supportability position."," For each product: does the vendor ship JVM updates, do they support replacing the bundled runtime, and which JDK builds do they certify?",[38,646,647,650,651,654],{},[20,648,649],{},"Patch what can be patched."," Through vendor updates or supported runtime swaps, rolled out with the same ",[75,652,653],{"href":215},"detection and rollback discipline"," as your own apps.",[38,656,657,660],{},[20,658,659],{},"Protect what can't."," Network isolation, disabling vulnerable features, tighter access. The compensating controls are documented so your risk register reflects reality.",[38,662,663,666],{},[20,664,665],{},"Take it to the vendor."," Certified-JDK questions, SBOM requests and patch-timeline commitments, backed by the specific evidence you need for a contract conversation.",[84,668,669],{},[16,670,671],{},"Some commercial products include a restricted Oracle Java license for use with that product only. Whether a bundled Oracle runtime creates licensing exposure depends on the product's terms, so we check them rather than assuming either way.",{"title":229,"searchDepth":230,"depth":231,"links":673},[674,675],{"id":610,"depth":230,"text":611},{"id":295,"depth":230,"text":296},"third-party-apps","Advisory for the Java you don't build yourself, including commercial products, appliances and vendor-bundled runtimes, so they get patched or protected instead of forgotten.","Advisory engagement scoped per vendor portfolio, usually following a discovery engagement that surfaces the bundled runtimes.","Second- and third-party apps","i-lucide-package",{},5,[684,685,686,687],"Every vendor-bundled JVM identified and attributed to a product and owner","A supportability position for each (vendor update, supported JRE swap or neither)","Compensating controls where patching isn't possible",{"Vendor asks backed by evidence":688},"certified JDKs, SBOMs, patch timelines","\u002Fservices\u002Fthird-party-applications",{"title":605,"description":677},"services\u002Fthird-party-applications","oy1ThKLwcn-G3Z5DaUWp8Maj1EXsbbInm5duRfzyfRs",{"id":694,"title":196,"body":695,"category":238,"description":763,"engagement":764,"extension":241,"headline":202,"icon":765,"meta":766,"navigation":245,"order":767,"outcomes":768,"path":195,"seo":773,"stem":774,"__hash__":775},"services\u002Fservices\u002Fdrift-monitoring.md",{"type":8,"value":696,"toc":758},[697,701,704,707,711,747,751],[11,698,700],{"id":699},"assessments-go-stale","Assessments go stale",[16,702,703],{},"An estate assessment is accurate the day it's delivered. After that, teams deploy new services, vendors ship updates with new bundled runtimes, someone installs Oracle JDK on a build agent, and a new CVE lands against a version you thought was fine.",[16,705,706],{},"Continuous Drift Monitoring keeps the picture current. The inventory becomes a system of record instead of a PDF.",[11,708,710],{"id":709},"what-it-watches","What it watches",[35,712,713,719,725,731,737],{},[38,714,715,718],{},[20,716,717],{},"New and undocumented JVMs"," across hosts, containers and artifact repositories",[38,720,721,724],{},[20,722,723],{},"Patch-level drift",": which runtimes fell behind after each quarterly critical patch update",[38,726,727,730],{},[20,728,729],{},"New CVEs"," against the versions and dependencies you actually run",[38,732,733,736],{},[20,734,735],{},"License exposure changes",": a new Oracle JDK install is flagged before it shows up in an audit",[38,738,739,742,743,746],{},[20,740,741],{},"Classification triggers",", such as a new regulated data flow, a traffic spike or an incident, which force an application's ",[75,744,745],{"href":77},"risk tier"," to be re-scored",[11,748,750],{"id":749},"how-its-delivered","How it's delivered",[16,752,753,754,757],{},"Collection reuses the minimum-privilege methods from the ",[75,755,756],{"href":253},"original assessment",". Findings go to a shared dashboard and to the channels your teams already use. Each quarter, aligned to the Java patch calendar, we review drift, exposure and upcoming end-of-life dates with you.",{"title":229,"searchDepth":230,"depth":231,"links":759},[760,761,762],{"id":699,"depth":230,"text":700},{"id":709,"depth":230,"text":710},{"id":749,"depth":230,"text":750},"Keep your JVM inventory, patch posture and Oracle license exposure current as the estate changes, instead of commissioning a new assessment every year.","Ongoing subscription after an estate assessment. Continuous collection, alerting on meaningful changes, and a quarterly review aligned to the Java patch calendar.","i-lucide-refresh-cw",{},6,[769,770,771,772],"New and undocumented JVMs detected as they appear","Patch-level drift tracked against each quarterly release","Alerts when a new install creates Oracle license exposure","Automatic re-classification when an app's risk profile changes",{"title":196,"description":763},"services\u002Fdrift-monitoring","Phmhi-GcB9IZ5dN4HFjsW_dg9QF_D9rXUNzILnRNAKE",{"id":777,"title":778,"author":779,"body":780,"category":488,"date":1204,"description":1205,"draft":1206,"extension":241,"featured":1206,"image":1207,"meta":1208,"navigation":245,"path":462,"readingTime":767,"seo":1209,"stem":1210,"tags":1211,"updated":1207,"__hash__":1218},"articles\u002Farticles\u002Fjvm-patch-failure-modes.md","Six ways JVM changes break production, and how to see them coming","patchmageddon-team",{"type":8,"value":781,"toc":1193},[782,785,788,792,883,891,895,902,908,913,927,933,937,940,945,949,960,969,973,976,981,986,991,995,998,1003,1007,1018,1023,1027,1030,1060,1076,1093,1102,1106,1109,1114,1119,1131,1135,1138,1165,1177,1181],[16,783,784],{},"When a JVM change breaks something in production, it rarely fails in a new way. Most incidents fall into a short list of patterns that repeat across organizations and releases. If you know the list, you can check for each item before rollout instead of discovering it afterwards.",[16,786,787],{},"First, though, it matters what kind of change you're making.",[11,789,791],{"id":790},"not-every-jvm-patch-carries-the-same-risk","Not every \"JVM patch\" carries the same risk",[130,793,794,810],{},[133,795,796],{},[136,797,798,801,804,807],{},[139,799,800],{},"Failure mode",[139,802,803],{},"Same-major security update (e.g. 17.0.x → 17.0.y)",[139,805,806],{},"Major version upgrade (e.g. 11 → 17 → 21)",[139,808,809],{},"Vendor swap, same version (e.g. Oracle JDK → Temurin)",[152,811,812,825,837,848,859,871],{},[136,813,814,817,820,823],{},[157,815,816],{},"APM and instrumentation agents",[157,818,819],{},"Occasionally",[157,821,822],{},"Frequently",[157,824,819],{},[136,826,827,830,832,834],{},[157,828,829],{},"TLS and cipher defaults",[157,831,819],{},[157,833,822],{},[157,835,836],{},"Rarely",[136,838,839,842,844,846],{},[157,840,841],{},"JIT and warm-up behavior",[157,843,836],{},[157,845,819],{},[157,847,836],{},[136,849,850,853,855,857],{},[157,851,852],{},"GC defaults and flags",[157,854,836],{},[157,856,822],{},[157,858,836],{},[136,860,861,864,867,869],{},[157,862,863],{},"Removed APIs and encapsulation",[157,865,866],{},"No",[157,868,822],{},[157,870,866],{},[136,872,873,876,879,881],{},[157,874,875],{},"Container awareness",[157,877,878],{},"Only on very old builds",[157,880,819],{},[157,882,878],{},[16,884,885,886,890],{},"The frequencies are our qualitative judgment, not measured rates. The pattern is what matters: same-major security updates are low-risk, and most serious breakage comes with major upgrades. That's why they should be planned and governed differently (see ",[75,887,889],{"href":888},"\u002Fapproach","our approach",").",[11,892,894],{"id":893},"_1-apm-and-instrumentation-agents","1. APM and instrumentation agents",[16,896,897,898,901],{},"APM, security and profiling tools usually attach to the JVM as Java agents (",[331,899,900],{},"-javaagent",") and rewrite bytecode as classes load. To do that they have to understand the class file format and, often, parts of the JDK's internals.",[16,903,904,907],{},[20,905,906],{},"Symptom:"," The application fails to start, logs errors from the agent, or runs normally while the agent silently stops reporting. On major upgrades, an older agent may simply not support the newer class file version.",[16,909,910],{},[20,911,912],{},"Detect before rollout:",[35,914,915,921,924],{},[38,916,917,918],{},"Inventory which agents, and which versions, are attached to each JVM. Check the startup command line and environment variables such as ",[331,919,920],{},"JAVA_TOOL_OPTIONS",[38,922,923],{},"Check each vendor's supported-JDK matrix for the target version",[38,925,926],{},"In the canary stage, gate on \"the agent is reporting,\" not just \"the app is up\"",[16,928,929,932],{},[20,930,931],{},"Mitigate:"," Upgrade the agent before, or together with, the JVM. For major upgrades, test the agent on the target JDK first.",[11,934,936],{"id":935},"_2-tls-and-cipher-suite-defaults","2. TLS and cipher suite defaults",[16,938,939],{},"JDK updates regularly tighten security defaults: disabling old protocol versions, removing weak cipher suites, and distrusting certain root certificates. A notable example: TLS 1.0 and 1.1 were disabled by default across supported Java releases in the April 2021 updates.",[16,941,942,944],{},[20,943,906],{}," Handshake failures when connecting to older partners, appliances, databases, mainframe gateways or internal services still using old protocols or ciphers. These often appear only in specific integrations, which is why they slip through generic testing.",[16,946,947],{},[20,948,912],{},[35,950,951,954,957],{},[38,952,953],{},"Read the release notes for security-default changes. They're usually listed explicitly",[38,955,956],{},"Inventory the outbound TLS endpoints each application talks to, and test handshakes against them from a patched JVM",[38,958,959],{},"Watch handshake failure rates during the canary stage",[16,961,962,964,965,968],{},[20,963,931],{}," Fix the far end where you can. Re-enabling a disabled protocol in ",[331,966,967],{},"java.security"," is sometimes necessary as a stopgap. Make it a documented, time-limited exception, not a silent config change.",[11,970,972],{"id":971},"_3-jit-compilation-and-warm-up","3. JIT compilation and warm-up",[16,974,975],{},"The JIT compiler improves between releases, but \"different\" isn't always \"better\" for every workload. Changes in inlining, compilation thresholds or tiered compilation can shift how quickly an application reaches steady-state performance.",[16,977,978,980],{},[20,979,906],{}," Higher latency for the first minutes after startup, or a changed p99 on latency-sensitive services. Startup-time SLOs and autoscaling behavior are affected first.",[16,982,983,985],{},[20,984,912],{}," Measure time-to-steady-state and tail latency on a canary under real traffic, not only in a quiet test environment.",[16,987,988,990],{},[20,989,931],{}," Usually no action is needed for same-major updates. For latency-critical services on major upgrades, plan a performance check and consider warm-up traffic before instances join the load balancer.",[11,992,994],{"id":993},"_4-gc-defaults-and-tuning-flags","4. GC defaults and tuning flags",[16,996,997],{},"Garbage collector defaults and options change across major versions. G1 has been the default collector since JDK 9. The CMS collector was deprecated in JDK 9 and removed in JDK 14. Many tuning flags accumulated over years of Java 8 operations are deprecated, ignored or rejected on newer releases.",[16,999,1000,1002],{},[20,1001,906],{}," The JVM refuses to start because of an unrecognized option, or it starts and ignores a flag, changing memory and pause behavior. Pause times, heap usage or throughput shift after the upgrade.",[16,1004,1005],{},[20,1006,912],{},[35,1008,1009,1012,1015],{},[38,1010,1011],{},"Collect the actual JVM flags from every instance during discovery, not just from documentation",[38,1013,1014],{},"Validate flags against the target version before rollout",[38,1016,1017],{},"Compare GC pause time and frequency between canary and baseline",[16,1019,1020,1022],{},[20,1021,931],{}," Clean up flags as part of the upgrade. For most applications on modern JDKs, fewer hand-tuned GC flags is better than carrying old ones forward.",[11,1024,1026],{"id":1025},"_5-removed-apis-and-strong-encapsulation","5. Removed APIs and strong encapsulation",[16,1028,1029],{},"This is the main source of breakage on major upgrades. Examples:",[35,1031,1032,1042,1048,1054],{},[38,1033,1034,1037,1038,1041],{},[20,1035,1036],{},"Strong encapsulation of JDK internals:"," JDK 16 (JEP 396) enabled strong encapsulation by default, and JDK 17 (JEP 403) removed the command-line option that relaxed it globally. Libraries that reached into ",[331,1039,1040],{},"sun.*"," and other internal packages via reflection can fail",[38,1043,1044,1047],{},[20,1045,1046],{},"The Security Manager:"," deprecated for removal in JDK 17 (JEP 411) and permanently disabled in JDK 24 (JEP 486). Applications and frameworks that rely on it need a different approach",[38,1049,1050,1053],{},[20,1051,1052],{},"The Nashorn JavaScript engine:"," removed in JDK 15. Applications that evaluated JavaScript through the scripting API need a replacement",[38,1055,1056,1059],{},[20,1057,1058],{},"Java EE modules"," such as JAXB and JAX-WS were removed from the JDK in JDK 11 and must now be added as explicit dependencies",[16,1061,1062,634,1064,1067,1068,1071,1072,1075],{},[20,1063,906],{},[331,1065,1066],{},"InaccessibleObjectException",", ",[331,1069,1070],{},"ClassNotFoundException"," or ",[331,1073,1074],{},"NoSuchMethodError"," at startup or, worse, only on a rarely used code path.",[16,1077,1078,1080,1081,1084,1085,1088,1089,1092],{},[20,1079,912],{}," Static analysis finds most of this before anyone patches anything. The JDK's own ",[331,1082,1083],{},"jdeps"," tool (including ",[331,1086,1087],{},"jdeps --jdk-internals",") reports use of internal APIs, and ",[331,1090,1091],{},"jdeprscan"," reports use of deprecated APIs. Check library versions against their documented JDK support.",[16,1094,1095,1097,1098,1101],{},[20,1096,931],{}," Upgrade the offending libraries. Use targeted ",[331,1099,1100],{},"--add-opens"," flags only as a documented, temporary exception.",[11,1103,1105],{"id":1104},"_6-container-awareness","6. Container awareness",[16,1107,1108],{},"Early Java 8 builds sized the heap and thread pools from the host's resources, not the container's CPU and memory limits. Proper container support arrived in JDK 10 and was backported to Java 8 in update 191 (8u191).",[16,1110,1111,1113],{},[20,1112,906],{}," Containers killed for exceeding memory limits, or JVMs using far more GC and compiler threads than the container has CPUs.",[16,1115,1116,1118],{},[20,1117,912],{}," Discovery should flag any Java 8 runtime older than 8u191 running in a container. These are also, almost by definition, badly out of date on security patches.",[16,1120,1121,1123,1124,1127,1128,227],{},[20,1122,931],{}," Update the runtime. Then review any hard-coded ",[331,1125,1126],{},"-Xmx"," values set as a workaround, and prefer percentage-based sizing such as ",[331,1129,1130],{},"-XX:MaxRAMPercentage",[11,1132,1134],{"id":1133},"turning-the-list-into-a-checklist","Turning the list into a checklist",[16,1136,1137],{},"For each application, before a JVM change:",[1139,1140,1141,1144,1147,1150,1153,1162],"ol",{},[38,1142,1143],{},"Which agents are attached, and do they support the target version?",[38,1145,1146],{},"What outbound TLS endpoints does it use, and do they work against the new defaults?",[38,1148,1149],{},"Is it latency-sensitive enough to need a warm-up check?",[38,1151,1152],{},"Which JVM flags are set, and are they all valid on the target?",[38,1154,1155,1156,1158,1159,1161],{},"For major upgrades: what do ",[331,1157,1083],{}," and ",[331,1160,1091],{}," report?",[38,1163,1164],{},"If containerized: is the runtime container-aware?",[16,1166,1167,1168,1172,1173,227],{},"Most of these questions are answered by a good inventory. See ",[75,1169,1171],{"href":1170},"\u002Farticles\u002Ffinding-every-jvm-in-your-estate","finding every JVM in your estate",". The rest are covered by canary gates, described in ",[75,1174,1176],{"href":1175},"\u002Farticles\u002Ffast-detection-and-rollback-instead-of-regression-testing","fast detection and rollback",[11,1178,1180],{"id":1179},"what-to-do-next","What to do next",[16,1182,1183,1184,1186,1187,1189,1190,227],{},"For same-major security updates on low-criticality apps, ",[75,1185,216],{"href":215}," builds these checks into the rollout. For business-critical systems and major upgrades, ",[75,1188,221],{"href":220}," includes a readiness assessment that runs this analysis before any patch is attempted. If you're also changing vendors, see the ",[75,1191,1192],{"href":356},"Oracle JDK to OpenJDK migration checklist",{"title":229,"searchDepth":230,"depth":231,"links":1194},[1195,1196,1197,1198,1199,1200,1201,1202,1203],{"id":790,"depth":230,"text":791},{"id":893,"depth":230,"text":894},{"id":935,"depth":230,"text":936},{"id":971,"depth":230,"text":972},{"id":993,"depth":230,"text":994},{"id":1025,"depth":230,"text":1026},{"id":1104,"depth":230,"text":1105},{"id":1133,"depth":230,"text":1134},{"id":1179,"depth":230,"text":1180},"2026-08-11","APM agents, TLS defaults, JIT warm-up, GC changes, removed APIs and container awareness: how each JVM failure mode shows up, and how to catch it before rollout.",false,null,{},{"title":778,"description":1205},"articles\u002Fjvm-patch-failure-modes",[1212,1213,1214,1215,1216,1217],"jvm-upgrade","failure-modes","tls","garbage-collection","java-agents","testing","7D2YYirroTkpbNNavdjU7NPhnH4Gov_4WWffi-fboDg",{"id":1220,"avatar":1221,"bio":1222,"extension":1223,"kind":1224,"links":1225,"meta":1230,"name":1231,"role":1232,"stem":1233,"__hash__":1234},"authors\u002Fauthors\u002Fpatchmageddon-team.yml","\u002Ffavicon.svg","The Patchmageddon team helps enterprises find every JVM in their estate, patch it on a sane cadence, and stop paying for Oracle Java they don't need.","yml","organization",[1226],{"label":1227,"icon":1228,"to":1229},"LinkedIn","i-simple-icons-linkedin","https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Fpatchmageddon",{},"Patchmageddon Team","JVM patching & OpenJDK migration specialists","authors\u002Fpatchmageddon-team","4HFxqSUgKzMH-9PhrByUwSJBQRn96t7Og1rkYrP4XnM",[1236],{"id":1237,"title":1238,"author":779,"body":1239,"category":488,"date":1655,"description":1656,"draft":1206,"extension":241,"featured":1206,"image":1207,"meta":1657,"navigation":245,"path":1175,"readingTime":682,"seo":1658,"stem":1659,"tags":1660,"updated":1207,"__hash__":1665},"articles\u002Farticles\u002Ffast-detection-and-rollback-instead-of-regression-testing.md","Fast detection and rollback: a safer alternative to full regression testing",{"type":8,"value":1240,"toc":1642},[1241,1244,1247,1251,1254,1260,1263,1266,1273,1281,1284,1287,1307,1310,1313,1317,1320,1370,1377,1456,1459,1462,1465,1485,1488,1492,1495,1499,1510,1514,1540,1587,1592,1596,1618,1622,1629,1631,1638],[16,1242,1243],{},"Oracle and the OpenJDK update projects ship scheduled security updates four times a year, in January, April, July and October, usually around the third Tuesday of the month. Many enterprises need most of a quarter to get a JVM update through regression testing across their applications. Some never finish before the next one arrives.",[16,1245,1246],{},"For business-critical systems, thorough testing is worth the time. For the long tail of internal tools, batch jobs and low-traffic services, it usually isn't. For that tier there's a better approach than either testing everything or skipping tests.",[11,1248,1250],{"id":1249},"the-argument","The argument",[16,1252,1253],{},"Think about the expected cost of a bad patch reaching production:",[1255,1256,1257],"blockquote",{},[16,1258,1259],{},"expected cost ≈ probability of a problem × impact per minute × minutes until it's fixed",[16,1261,1262],{},"Full regression testing attacks the first term, making a problem less likely to ship. Fast detection and fast rollback attack the last term, making any problem that does ship short-lived.",[16,1264,1265],{},"For a same-major JVM security update, such as moving between two 17.0.x releases, the chance of a functional regression is already low. For a low-criticality application the impact per minute is also low. If you can detect a problem in minutes and reverse it in minutes, the expected cost of skipping a multi-week regression cycle is small, and usually much smaller than leaving known CVEs open for another quarter.",[16,1267,1268,1269,1272],{},"That's the core claim: ",[20,1270,1271],{},"when mean time to detect (MTTD) and mean time to recover (MTTR) are low, the value of full pre-deployment regression testing drops sharply."," It holds only if both numbers really are low, so most of the work goes into making them low.",[84,1274,1275],{},[16,1276,1277,1278,227],{},"This approach applies to same-major security updates on applications classified as low-criticality through a documented process. Major version upgrades and vendor swaps carry different risks. See ",[75,1279,1280],{"href":462},"JVM patch failure modes",[11,1282,434],{"id":1283},"progressive-rollout",[16,1285,1286],{},"Don't patch everything at once. Roll out in stages, with automated checks between each one:",[1139,1288,1289,1295,1301],{},[38,1290,1291,1294],{},[20,1292,1293],{},"Canary (about 1%):"," one instance or a small slice of traffic. Hold long enough to see steady-state behavior, not just startup",[38,1296,1297,1300],{},[20,1298,1299],{},"Partial (about 10%):"," enough traffic that low-frequency errors show up",[38,1302,1303,1306],{},[20,1304,1305],{},"Full (100%):"," complete the rollout, then keep watching through a soak period",[16,1308,1309],{},"Each step is gated. If a gate fails, the rollout stops and rolls back automatically, with no meeting required.",[16,1311,1312],{},"For small applications running on one or two instances, \"1%\" becomes \"one instance first, then the rest.\" The principle is the same: expose the change to real load in a limited way before exposing all of it.",[11,1314,1316],{"id":1315},"what-to-watch-on-a-jvm-change","What to watch on a JVM change",[16,1318,1319],{},"Generic health checks, like \"is the process up?\", miss most JVM-specific regressions. Compare the patched instances against the unpatched baseline on these signals:",[35,1321,1322,1328,1334,1340,1346,1352,1358,1364],{},[38,1323,1324,1327],{},[20,1325,1326],{},"Error rate:"," HTTP 5xx, exception counts, failed jobs",[38,1329,1330,1333],{},[20,1331,1332],{},"Latency:"," p50 and p99, since JVM changes often affect the tail first",[38,1335,1336,1339],{},[20,1337,1338],{},"GC behavior:"," pause time, pause frequency and collection counts",[38,1341,1342,1345],{},[20,1343,1344],{},"Memory:"," heap after GC, metaspace and native memory where you can measure it",[38,1347,1348,1351],{},[20,1349,1350],{},"Threads:"," thread counts and blocked threads",[38,1353,1354,1357],{},[20,1355,1356],{},"Warm-up:"," time to reach steady-state latency after start",[38,1359,1360,1363],{},[20,1361,1362],{},"TLS:"," handshake failures to downstream systems, which point to protocol or cipher changes",[38,1365,1366,1369],{},[20,1367,1368],{},"Agent health:"," whether APM and security agents attached and are reporting",[16,1371,1372,1373,1376],{},"Example gates might look like this. The thresholds are ",[20,1374,1375],{},"illustrative only"," and should be tuned to each application's normal variance:",[130,1378,1379,1392],{},[133,1380,1381],{},[136,1382,1383,1386,1389],{},[139,1384,1385],{},"Signal",[139,1387,1388],{},"Compared against",[139,1390,1391],{},"Example gate",[152,1393,1394,1405,1415,1425,1435,1446],{},[136,1395,1396,1399,1402],{},[157,1397,1398],{},"Error rate",[157,1400,1401],{},"Unpatched baseline",[157,1403,1404],{},"Fail if more than 1.5× baseline over 10 minutes",[136,1406,1407,1410,1412],{},[157,1408,1409],{},"p99 latency",[157,1411,1401],{},[157,1413,1414],{},"Fail if more than 20% higher over 15 minutes",[136,1416,1417,1420,1422],{},[157,1418,1419],{},"GC pause time (p99)",[157,1421,1401],{},[157,1423,1424],{},"Fail if more than 50% higher",[136,1426,1427,1430,1432],{},[157,1428,1429],{},"Heap after GC",[157,1431,1401],{},[157,1433,1434],{},"Flag a steady upward trend across the hold period",[136,1436,1437,1440,1443],{},[157,1438,1439],{},"TLS handshake failures",[157,1441,1442],{},"Absolute",[157,1444,1445],{},"Fail on any sustained increase",[136,1447,1448,1451,1453],{},[157,1449,1450],{},"APM agent reporting",[157,1452,1442],{},[157,1454,1455],{},"Fail if the agent stops reporting",[16,1457,1458],{},"Comparing against a live unpatched baseline, rather than fixed numbers, removes most false alarms caused by normal traffic swings.",[11,1460,452],{"id":1461},"smoke-tests-and-synthetic-transactions",[16,1463,1464],{},"Replace the full regression suite with a small set of checks that exercise what matters:",[35,1466,1467,1473,1479],{},[38,1468,1469,1472],{},[20,1470,1471],{},"Smoke tests"," run right after each instance starts: does the app start, connect to its database and queue, and serve its health endpoint?",[38,1474,1475,1478],{},[20,1476,1477],{},"Synthetic transactions"," run continuously: scripted logins, searches, report generations, or whatever the app's two or three core paths are",[38,1480,1481,1484],{},[20,1482,1483],{},"Integration probes"," hit each external dependency, which is especially useful for catching TLS problems",[16,1486,1487],{},"These run in minutes, can be kept current easily, and exercise the code paths a JVM change is most likely to disturb.",[11,1489,1491],{"id":1490},"making-rollback-fast","Making rollback fast",[16,1493,1494],{},"Fast rollback is often the actual gap. In many enterprise estates, particularly outside containers, reverting a JVM means a manual change, a ticket and a wait. Fix that first. Without it, none of the above is safe.",[298,1496,1498],{"id":1497},"in-containerized-environments","In containerized environments",[35,1500,1501,1504,1507],{},[38,1502,1503],{},"Treat images as immutable and version them. Rolling back means redeploying the previous image tag",[38,1505,1506],{},"Keep the previous image available and tested until the soak period ends",[38,1508,1509],{},"Have the deployment tooling perform the rollback automatically when a gate fails",[298,1511,1513],{"id":1512},"on-vms-and-bare-metal","On VMs and bare metal",[35,1515,1516,1522,1528,1534],{},[38,1517,1518,1521],{},[20,1519,1520],{},"Install side by side."," Put the new JDK in its own versioned directory and switch the application to it using a symlink, environment variable or service configuration. Don't overwrite the old one",[38,1523,1524,1527],{},[20,1525,1526],{},"Don't uninstall the previous runtime"," until the soak period has passed",[38,1529,1530,1533],{},[20,1531,1532],{},"Script the switch"," in both directions, and make sure the application restarts cleanly with either runtime",[38,1535,1536,1539],{},[20,1537,1538],{},"Rehearse it."," A rollback nobody has run is a hypothesis, not a procedure",[1541,1542,1546],"pre",{"className":1543,"code":1544,"language":1545,"meta":229,"style":229},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","# Illustrative side-by-side layout on a Linux host\n\u002Fopt\u002Fjava\u002Fjdk-17.0.15\u002F\n\u002Fopt\u002Fjava\u002Fjdk-17.0.16\u002F\n\u002Fopt\u002Fjava\u002Fcurrent -> \u002Fopt\u002Fjava\u002Fjdk-17.0.16   # rollback = repoint and restart\n","bash",[331,1547,1548,1556,1562,1567],{"__ignoreMap":229},[1549,1550,1552],"span",{"class":1551,"line":246},"line",[1549,1553,1555],{"class":1554},"sutJx","# Illustrative side-by-side layout on a Linux host\n",[1549,1557,1558],{"class":1551,"line":230},[1549,1559,1561],{"class":1560},"sbgvK","\u002Fopt\u002Fjava\u002Fjdk-17.0.15\u002F\n",[1549,1563,1564],{"class":1551,"line":231},[1549,1565,1566],{"class":1560},"\u002Fopt\u002Fjava\u002Fjdk-17.0.16\u002F\n",[1549,1568,1569,1572,1576,1580,1584],{"class":1551,"line":594},[1549,1570,1571],{"class":1560},"\u002Fopt\u002Fjava\u002Fcurrent",[1549,1573,1575],{"class":1574},"su5hD"," -",[1549,1577,1579],{"class":1578},"smGrS",">",[1549,1581,1583],{"class":1582},"s_sjI"," \u002Fopt\u002Fjava\u002Fjdk-17.0.16",[1549,1585,1586],{"class":1554},"   # rollback = repoint and restart\n",[288,1588,1589],{},[16,1590,1591],{},"If rolling back a JVM on a given application takes hours, that application isn't ready for reduced pre-deployment testing yet, whatever its criticality score. Make rollback fast first.",[11,1593,1595],{"id":1594},"where-this-doesnt-apply","Where this doesn't apply",[35,1597,1598,1606,1612],{},[38,1599,1600,1603,1604],{},[20,1601,1602],{},"Business-critical applications:"," keep rigorous testing and make it faster with risk-based test selection and shadow traffic. See ",[75,1605,221],{"href":220},[38,1607,1608,1611],{},[20,1609,1610],{},"Major version upgrades:"," removed APIs and changed defaults need targeted assessment before any rollout",[38,1613,1614,1617],{},[20,1615,1616],{},"Apps without observability:"," if you can't see errors and latency, you can't gate on them",[11,1619,1621],{"id":1620},"getting-it-approved","Getting it approved",[16,1623,1624,1625,1628],{},"The technical case is only half the work. A Change Advisory Board also has to accept the process. Our guide to ",[75,1626,1627],{"href":480},"getting faster JVM patching past the CAB"," covers classification, the standard change model and the evidence to keep.",[11,1630,1180],{"id":1179},[16,1632,1633,1635,1636,227],{},[75,1634,216],{"href":215}," is our service built on this model, including fixing rollback where it's missing. The full method is described in ",[75,1637,889],{"href":888},[1639,1640,1641],"style",{},"html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":229,"searchDepth":230,"depth":231,"links":1643},[1644,1645,1646,1647,1648,1652,1653,1654],{"id":1249,"depth":230,"text":1250},{"id":1283,"depth":230,"text":434},{"id":1315,"depth":230,"text":1316},{"id":1461,"depth":230,"text":452},{"id":1490,"depth":230,"text":1491,"children":1649},[1650,1651],{"id":1497,"depth":231,"text":1498},{"id":1512,"depth":231,"text":1513},{"id":1594,"depth":230,"text":1595},{"id":1620,"depth":230,"text":1621},{"id":1179,"depth":230,"text":1180},"2026-08-18","For low-criticality apps, quick detection and cheap rollback cut JVM patch risk more than a full regression run. Here's how to build that safety net.",{},{"title":1238,"description":1656},"articles\u002Ffast-detection-and-rollback-instead-of-regression-testing",[1283,1661,1662,1663,1664],"rollback","observability","canary","patch-cadence","x601uJ3l6gvr8R_-xeLIFcM-IUG414z9IKmZwMgoqTE",[1667,1668],{"title":1238,"path":1175,"stem":1659,"description":1656,"children":-1},{"title":1669,"path":1670,"stem":1671,"description":1672,"children":-1},"Patching the JVMs you didn't install: Java inside vendor products","\u002Farticles\u002Fpatching-jvms-inside-vendor-products","articles\u002Fpatching-jvms-inside-vendor-products","Many commercial products ship their own Java runtime. Why scanners miss them, what vendors will support, and how to handle the ones you can't patch yourself.",1790355850287]