HtmlUnit 5.0.0 - A Major Milestone
HtmlUnit 5.0.0 has been released — a major milestone for the project! This is the first release to require JDK 17 or higher, which opens the door to modernizing the codebase further in the releases to come. Let’s take a look at the highlights.
🚀 The Big One: JDK 17 Baseline
Starting with 5.0.0, Java 17 is the minimum required version. All sub-projects — htmlunit-neko, htmlunit-csp, htmlunit-cssparser, htmlunit-corejs,
and htmlunit-xpath — have been updated accordingly. Along with this, module-info.java has been added to all projects, making HtmlUnit a proper set of named Java modules.
If you are still on JDK 8, the 4.x branch remains available. See the Legacy Support section in the README for details.
The Xerces dependency has also been cleaned up as part of this modernization: XmlUtilsXercesHelper, XmlUtilsSunXercesHelper, and XmlUtilsHelperAPI have been removed,
and the xercesImpl runtime dependency is gone.
🔐 SubtleCrypto — Real Implementation
This is big. Thanks to the outstanding work of Lai Quang Duong, SubtleCrypto now has a real implementation covering the most important Web Crypto API operations:
- digest() — SHA-1, SHA-256, SHA-384, SHA-512
- generateKey() — RSASSA-PKCS1-v1_5, RSA-PSS, RSA-OAEP, ECDSA, ECDH, AES-CBC, AES-CTR, AES-GCM, AES-KW, HMAC
- importKey() / exportKey() — raw format for symmetric algorithms
- sign() / verify() — HMAC, RSASSA-PKCS1-v1_5, RSA-PSS, ECDSA
- encrypt() / decrypt() — AES-CBC, AES-GCM, AES-CTR, RSA-OAEP
This is a massive step forward for testing modern web applications that rely on the Web Crypto API.
⚙️ JavaScript Engine (core-js)
The Rhino team continues to deliver, with further improvements in 5.0.0:
- Major refactoring to properly separate the top-level scope from
globalThis IdFunctionObject.isConstructor()fixed — methods likeDate.prototype.getDateandRegExp.prototype.execno longer incorrectly report themselves as constructorsRegExp.prototype[Symbol.split]andRegExp.prototype[Symbol.replace]received major performance improvements- Resizable
ArrayBuffersupport as per ES2024 added DataViewnow supportsFloat16,BigInt64, andBigUInt64JSON.parsefixed to preserve negative zeroSymbol.hasInstancecustom implementations are now respected; prototype chain lookup works correctly- Rest parameters in destructuring are now supported
NativeDatemigrated away fromIdScriptableObjectWrapFactoryAPI tightened — users must now override the newwrap(...)andwrapAsJavaObject(...)methodsgenerator.return()now correctly includes the value when the generator is in a completed state- Automatic semicolon insertion for
letfixed ClassSizeExceptionintroduced for better class compilation error reporting- Internal cleanup: dropped support for legacy engine versions 1.0–1.4
🔌 WebSocket Overhaul
The WebSocket support has been significantly hardened and cleaned up:
- The WebSocket constructor now properly validates the URL and throws the correct error types
- Socket connect errors are handled correctly — status is set and listeners are triggered
- The
was cleanflag on close events is now only set when the status code is 1000, matching the spec - Incompatible change:
WebSocketListener.onWebSocketBinary(byte[], int, int)has been replaced withonWebSocketBinary(ByteBuffer payload) - Incompatible change:
WebSocketAdapter.closeIncommingSession()has been renamed to the correctly spelledcloseIncomingSession() - Incompatible change:
WebClientOptions.getWebSocketMaxTextMessageBufferSize()/getWebSocketMaxBinaryMessageBufferSize()and their setters have been removed - Jetty websocket-client updated to 12.1.8
🧩 New DOM & HTML Features
HtmlHeadingGroupintroduced —<hgroup>is now a first-class elementDocument.parseHTMLUnsafe()— first implementation addedHTMLAreaElementnow exposes all URL decomposition properties:hash,host,hostname,href,origin,password,pathname,port,protocol,search, andusernameHTMLHyperlinkElementUtilsextracted as shared base forHTMLAnchorElementandHTMLAreaElementDomNode.insertBefore()now correctly dissolvesDocumentFragmentinto its children before insertionselect.remove()with no arguments now correctly removes itself from the DOMHtmlInputElementtypesemail,url,date, andtimenow correctly fire theinputeventFileReadernow firesProgressEventand exposes all missing event handlerswindow.queueMicrotask()addedHtmlPageid/name lookup index is now built lazily on first read (performance improvement, thanks to Ronny Shapiro)
🔢 Intl Improvements
Intl.Localeimplementation addedIntl.supportedLocalesOf()added toDateTimeFormatandNumberFormatIntl.getCanonicalLocales()implementedtoStringsymbol fixed forIntl,Collator,DateTimeFormat,Locale, andNumberFormat
🎤 Speech API Support
The Web Speech API has arrived in HtmlUnit. SpeechRecognition, SpeechGrammar, and SpeechGrammarList are now implemented and exposed under both their standard names
and their webkit-prefixed variants (webkitSpeechRecognition, webkitSpeechGrammar, webkitSpeechGrammarList). The accompanying SpeechRecognitionEvent
and SpeechRecognitionErrorEvent are also included.
🐛 Neko HTML Parser
hgroupelement support added- html5lib test suite integrated for broader conformance coverage
- Null character handling in script content fixed
- Surrogate character reference parse error handling fixed
- Consecutive ampersands before named entity parsing fixed
- Invalid numeric entity handling improved
HTMLScanner.scanNamenow has an ASCII fast-path for the inner character loop
🌍 Browser Compatibility: Firefox 150, Chrome/Edge 148
As always, the browser simulation has been kept up to date:
- Firefox 150 and Chrome/Edge 148 are now supported
- Several
document.createEvent()calls now throw in Chrome/Edge to match current browser behaviour (WheelEvent,CloseEvent,AnimationEvent,PopStateEvent) - The
<command>HTML tag is no longer supported in Chrome/Edge NumberFormatforde-CHandit-CHlocales updated
📦 Other Incompatible Changes
Cookiemoved from packageorg.htmlunit.utiltoorg.htmlunit.http- Test suite migrated from JUnit 5 to JUnit 6
- Logging configuration in tests switched from log4j to logback-classic
Thank You!
A huge thank you to everyone who contributed to this release — Lai Quang Duong for the exceptional SubtleCrypto and DOM work, the Rhino Team for the continued JavaScript engine improvements, Ronny Shapiro and Kanoko Yamamoto for their contributions, and to everyone who filed bug reports and sent pull requests.
As always, 5.0.0 is available on Maven Central. Check out the full changes report for the complete list of changes.
Happy testing!
— RBRi
Resources:
- Changes Report — Detailed release notes
- HtmlUnit Homepage — Project information
- Maven Central — Download
- GitHub Repository — Source code