Hi yes, thanks for mentioning this.

In the context of API specifications, "immutable" often means that from the point of view of the public API, the state of the object cannot be observed to mutate. And yes it usually implies thread safety. Of course that's possible to achieve if none of the object's fields are mutated, but it's possible for such an object to have mutable fields. (String and BigInteger are examples of this.)

Unfortunately the CatalogImpl object is mutated to hold temporary state that's used during the resolution process. This temporary state doesn't really belong in the object itself, so it seems likely that a fix would involve refactoring this temporary state out of the Catalog itself into an object owned by some resolver object (or similar).

We'll take another look at the docs here to see if other updates are necessary.

s'marks

On 10/22/25 11:26 AM, Elliot Barlas wrote:
Thanks, Stuart.

Regarding specification, I noticed that the javax.xml.catalog package summary[1] indicates that "A Catalog object is immutable." Immutable typically indicates that internal state cannot be changed and it implies thread-safety. It might be worth clarifying the javadocs.

[1] https://docs.oracle.com/en/java/javase/25/docs/api/java.xml/javax/xml/catalog/package-summary.html

On Tue, Oct 21, 2025 at 8:51 PM Stuart Marks <[email protected]> wrote:

    Hi Elliot,

    Yes, this is indeed a bug. It seems that most of the XML and JAXP APIs 
aren't
    thread-safe and so must be used in a thread-confined manner. (Hm, I can't 
seem to
    find anything in the specifications about this... another thing to look 
at.) Most
    JAXP objects are constructed on demand. However, as you point out they end 
up
    using
    a shared CatalogImpl instance that represents the built-in JDK catalog. 
Since
    catalog resolution mutates this object, it's a thread-safety issue.

    I've filed

    https://bugs.openjdk.org/browse/JDK-8370379

    to cover this issue. Thanks for reporting it!

    s'marks

    On 10/14/25 3:07 PM, Elliot Barlas wrote:
    > Hello core-libs-dev!
    >
    > There appears to be a thread-safety bug in
    > com.sun.org.apache.xerces.internal.impl.XMLEntityManager related to the
    > introduction of the following field[1] in the following commit[2].
    >
    > [1] CatalogResolver fDefCR // the default JDK Catalog Resolver
    >
    > [2]
    
https://github.com/openjdk/jdk/commit/93bdc2a6db91a95d6ee52ec92080e586c694dad5
    
<https://urldefense.com/v3/__https://github.com/openjdk/jdk/commit/93bdc2a6db91a95d6ee52ec92080e586c694dad5__;!!ACWV5N9M2RV99hQ!PKgSj2SeuOr4MCd4_Gx6yYDTmkSwn_53v3toPNh3ULqgJTW8B-suL5Rj6p6AR4cKJLpmLTdheaA8UfTNna9xkM3nOhEn$>
    >
    > Multiple threads executing the following sample code use the same 
underlying
    > javax.xml.catalog.CatalogImpl obtained from
    > JdkXmlConfig.getInstance().getJdkCatalog(). CatalogImpl is not thread 
safe. The
    > resolveEntity method mutates the underlying JDK catalog[3].
    >
    > [3]
    >
    
https://github.com/openjdk/jdk/blob/master/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java#L279
    
<https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/master/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java*L279__;Iw!!ACWV5N9M2RV99hQ!PKgSj2SeuOr4MCd4_Gx6yYDTmkSwn_53v3toPNh3ULqgJTW8B-suL5Rj6p6AR4cKJLpmLTdheaA8UfTNna9xkHxYgLPG$>
    >
    > XMLEntityManager entityManager = new XMLEntityManager();
    > XMLResourceIdentifier resourceIdentifier = new XMLResourceIdentifierImpl(
    >         "http://example.com/dtd/sample.dtd
    
<https://urldefense.com/v3/__http://example.com/dtd/sample.dtd__;!!ACWV5N9M2RV99hQ!PKgSj2SeuOr4MCd4_Gx6yYDTmkSwn_53v3toPNh3ULqgJTW8B-suL5Rj6p6AR4cKJLpmLTdheaA8UfTNna9xkAFCYHAv$>",
    >         "sample.dtd",
    >         "http://example.com/base/
    
<https://urldefense.com/v3/__http://example.com/base/__;!!ACWV5N9M2RV99hQ!PKgSj2SeuOr4MCd4_Gx6yYDTmkSwn_53v3toPNh3ULqgJTW8B-suL5Rj6p6AR4cKJLpmLTdheaA8UfTNna9xkDeCD3yJ$>",
    >         "http://example.com/base/sample.dtd
    
<https://urldefense.com/v3/__http://example.com/base/sample.dtd__;!!ACWV5N9M2RV99hQ!PKgSj2SeuOr4MCd4_Gx6yYDTmkSwn_53v3toPNh3ULqgJTW8B-suL5Rj6p6AR4cKJLpmLTdheaA8UfTNna9xkA6PDux_$>");
    > entityManager.resolveEntity(resourceIdentifier);
    >
    > Prior to the commit above, this code did not access a shared JDK 
CatalogImpl.
    >
    > -Elliot Barlas

Reply via email to