DEV Community

Cover image for jsoup 1.23.1 is out: here's what actually changed
Rajen Trivedi
Rajen Trivedi

Posted on

jsoup 1.23.1 is out: here's what actually changed

jsoup 1.23.1 just dropped and this one is worth paying attention to. Not just a patch release. There are real parser speed gains, meaningful memory improvements, and a security fix that Android and server-side Java devs should know about.

Here's what changed and why it matters.


Add the dependency

Gradle (Groovy):

implementation 'org.jsoup:jsoup:1.23.1'
Enter fullscreen mode Exit fullscreen mode

Gradle (Kotlin DSL):

implementation("org.jsoup:jsoup:1.23.1")
Enter fullscreen mode Exit fullscreen mode

Maven:

<dependency>
  <groupId>org.jsoup</groupId>
  <artifactId>jsoup</artifactId>
  <version>1.23.1</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Performance

This was clearly the main focus of the release. Numbers are from OpenJDK 21 benchmarks.

String parsing is 18% faster on average.
The most common use case just got noticeably quicker.

Document doc = Jsoup.parse(htmlString);
Enter fullscreen mode Exit fullscreen mode

InputStream parsing is 11% faster.
Good news if you're parsing HTTP responses or file streams directly.

Document doc = Jsoup.parse(inputStream, "UTF-8", baseUri);
Enter fullscreen mode Exit fullscreen mode

Source position tracking is 70% faster.
If you use Parser.htmlParser().setTrackPosition(true), this is a big one. It was the slowest mode before. Not anymore.

Parser parser = Parser.htmlParser().setTrackPosition(true);
Document doc = Jsoup.parse(htmlString, baseUri, parser);
Enter fullscreen mode Exit fullscreen mode

Source-tracked DOMs use 58 to 65% less memory on medium to large documents.
And the gains hold under concurrent parsing without introducing new contention. If you parse in parallel, you get the memory savings without thread safety trade-offs.


Security fix

The Cleaner had an issue where malformed HTML could sneak markup through when cleaned with a custom Safelist that allowed certain raw-text elements.

// Custom Safelists with raw-text elements were affected
Safelist safelist = Safelist.relaxed().addTags("script");
String cleaned = Jsoup.clean(malformedHtml, safelist);
// In previous versions, some markup could survive this incorrectly
Enter fullscreen mode Exit fullscreen mode

Built-in Safelists like Safelist.basic() and Safelist.relaxed() are not affected. But if you built a custom Safelist with unusual raw-text tag permissions, update now.


What else changed

Better HTML spec alignment.
Parsing of noscript, CDATA, SVG, and MathML now aligns more closely with the HTML living standard. If your parser results on edge-case documents ever felt slightly off, this release tightens that up.

Spec-correct HTTP redirects.
Redirect handling is now safer and follows the HTTP spec more accurately. Fewer surprises when dealing with servers that do non-standard redirect chains.

Fast immutable Element#classList().
Returns an immutable view of the element's class list. Faster to call, safer to use since you can't accidentally mutate it.

Element el = doc.selectFirst("div.card");
Set<String> classes = el.classList();
// immutable, no defensive copy needed
System.out.println(classes); // [card, featured, active]
Enter fullscreen mode Exit fullscreen mode

Direct outer-HTML output to an Appendable.
You can now write an element's outer HTML directly to a StringBuilder, Writer, or any Appendable without going through a String allocation first.

StringBuilder sb = new StringBuilder();
element.outerHtml(sb);
// no intermediate String created
Enter fullscreen mode Exit fullscreen mode

Bug fixes across the board:

  • RCDATA parsing corrections
  • XML conversion edge cases
  • Tag-name handling
  • Cleaner link detection

Should you update?

Yes, especially if you:

  • Use setTrackPosition(true): the 70% speed gain alone is worth it
  • Parse large documents concurrently: the memory savings are real
  • Built a custom Safelist with raw-text elements: the security fix applies to you

For everyone else it's still an easy drop-in upgrade with no API changes.


Reference: jsoup releases on GitHub

Top comments (0)