Skip to content

Xpp3DomBuilder.createXmlReader: remove thread-unsafe system property manipulation - #393

Merged
slachiewicz merged 5 commits into
masterfrom
fix/xpp3dombuilder-system-property
Sep 11, 2026
Merged

slachiewicz merged 5 commits into
masterfrom
fix/xpp3dombuilder-system-property

Conversation

@elharo

@elharo elharo commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Xpp3DomBuilder.createXmlReader() clears and restores the global org.xml.sax.driver system property without synchronization (lines 119-129). In a multi-threaded environment like Maven parallel builds, one thread's clear/restore sequence interferes with other threads' reads of the same property. The code's own comment acknowledges: "There's a 'slight' problem with this an parallel maven: It does not work ;)"

The method already tries to directly instantiate com.sun.org.apache.xerces.internal.parsers.SAXParser first — which succeeds on all Oracle/OpenJDK JVMs. The system property manipulation fallback is both unnecessary and harmful.

Fix: Removed the system property manipulation entirely. If the direct instantiation fails, falls through to XMLReaderFactory.createXMLReader() without modifying any global state.

Fixes #392

@elharo
elharo requested a review from slachiewicz July 1, 2026 14:07
@slachiewicz slachiewicz added the bug Something isn't working label Jul 2, 2026
@slachiewicz
slachiewicz removed their request for review July 2, 2026 06:06
@elharo
elharo requested a review from Copilot July 24, 2026 10:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Removes thread-unsafe manipulation of the global org.xml.sax.driver system property from Xpp3DomBuilder.createXmlReader(), addressing a race condition in multi-threaded environments (e.g., Maven parallel builds) as described in issue #392.

Changes:

  • Removed clear/restore of org.xml.sax.driver from createXmlReader() and now directly falls back to XMLReaderFactory.createXMLReader().
  • Added a regression test asserting that Xpp3DomBuilder.build(...) does not modify org.xml.sax.driver.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/main/java/org/apache/maven/shared/utils/xml/Xpp3DomBuilder.java Removes thread-unsafe global system property manipulation when creating an XMLReader.
src/test/java/org/apache/maven/shared/utils/xml/Xpp3DomBuilderTest.java Adds a regression test to ensure build() does not change the SAX driver system property.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

build() must not touch org.xml.sax.driver, which is what this test
asserts. If that ever regresses, the test would leave the mutated value
behind and take unrelated tests down with it. Restoring in a finally
keeps the blast radius to this test, matching how OsTest handles system
properties.
@slachiewicz

Copy link
Copy Markdown
Member

Pushed two commits to this branch: merged current master (which now carries the #422 fix, so the branch builds green again), and addressed the review point on the new test.

The test now restores org.xml.sax.driver in a finally block. build() must not touch that property, which is exactly what the test asserts, but if that ever regresses the old form would leave the mutated value behind and take unrelated tests down with it. This keeps the blast radius to this test, matching how OsTest handles system properties here.

No change to Xpp3DomBuilder itself.

Verified: mvn -B verify on JDK 17 -> Tests run: 788, Failures: 0, Errors: 0. Spotless clean.

This comment was created with AI assistance.

@slachiewicz slachiewicz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The race is real and removing the clear/restore is the right fix: a thread reading org.xml.sax.driver during another thread's window saw it cleared, and no restore ordering can make that safe.

Two corrections to the description, for the record. On JDK 17 and 25 the direct com.sun.org.apache.xerces.internal.parsers.SAXParser instantiation fails with IllegalAccessException, because java.xml does not export that package, so XMLReaderFactory.createXMLReader() is the path actually taken there rather than a rarely used fallback. The fix still holds: the factory returns the same Xerces parser when the property is unset. The one behaviour change is that a user-set org.xml.sax.driver is now honoured, including a broken value, where the old code silently ignored it. That is what the property is documented to do.

The new test also passes on the old code, since with the property unset the old clear and restore were no-ops. It guards against a future regression rather than demonstrating this one.

Squash-merging, since the branch carries a master merge and two fixups.

Verified: probe on JDK 17 and 25 → direct instantiation throws IllegalAccessException, factory returns com.sun.org.apache.xerces.internal.parsers.SAXParser; CI green on all 12 jobs.

This comment was created with AI assistance.

@slachiewicz
slachiewicz merged commit 1515447 into master Sep 11, 2026
15 checks passed
@slachiewicz
slachiewicz deleted the fix/xpp3dombuilder-system-property branch September 11, 2026 07:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Xpp3DomBuilder.createXmlReader() system property race condition

3 participants