Skip to content

Add XmlService classloader fallback for ServiceLoader discovery - #12237

Merged
gnodet merged 2 commits into
masterfrom
fix/xmlservice-classloader-fallback
Jun 13, 2026
Merged

gnodet merged 2 commits into
masterfrom
fix/xmlservice-classloader-fallback

Conversation

@gnodet

@gnodet gnodet commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Extracted from #11742 (by @arturobernalg) to keep the classloader fix separate from the namespace-preservation fix (#11715).

When the thread context classloader cannot see the XmlService provider (e.g. in isolated plugin classloaders), the ServiceLoader.load(XmlService.class) call fails with IllegalStateException("No XmlService implementation found").

This change:

  • Tries XmlService.class.getClassLoader() first — this is the core realm classloader which always sees the provider
  • Falls back to the TCCL if the class's own classloader doesn't find it
  • The order (class CL → TCCL) is intentional: XmlService lives in the API module, and its classloader reliably sees the impl/maven-xml provider through Maven's core realm. The TCCL may be a plugin classrealm or an isolated classloader that cannot.

Test plan

  • XmlServiceLoadingTest verifies discovery works when TCCL is an empty URLClassLoader that cannot see the provider

Claude Code on behalf of Guillaume Nodet

Co-authored-by: Arturo Bernal abernal@apache.org

When the thread context classloader cannot see the XmlService
provider (e.g. in plugin classloaders), fall back to loading
via XmlService's own classloader. This prevents
IllegalStateException("No XmlService implementation found")
in environments where the TCCL is isolated.

Co-authored-by: Arturo Bernal <abernal@apache.org>
gnodet added a commit to arturobernalg/maven that referenced this pull request Jun 4, 2026
- Remove XmlService classloader fallback (extracted to PR apache#12237)
- Use MavenModelVersion to compute the minimum model version
  instead of hardcoding 4.0.0 as the fallback
- Align namespace/schemaLocation format strings with
  TransformerSupport conventions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet gnodet added this to the 4.0.0-rc-6 milestone Jun 10, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet
gnodet requested a review from cstamas June 12, 2026 14:50
@gnodet
gnodet merged commit 123b43a into master Jun 13, 2026
23 checks passed
@gnodet
gnodet deleted the fix/xmlservice-classloader-fallback branch June 13, 2026 07:49
@github-actions

Copy link
Copy Markdown
Contributor

@gnodet Please assign appropriate label to PR according to the type of change.

gnodet added a commit that referenced this pull request Jun 13, 2026
…1742)

* Fix #11715: preserve 4.1.0 namespace/schema in help:effective-pom

When generating the effective POM for a modelVersion 4.1.0 project,
preserve the root <project> namespace and schemaLocation as 4.1.0
instead of falling back to 4.0.0.

Add/keep coverage with MavenITgh11715EffectivePomNamespaceTest to
verify the effective POM header contains:
- xmlns http://maven.apache.org/POM/4.1.0
- schemaLocation .../maven-4.1.0.xsd

* Extract XmlService classloader fix and use MavenModelVersion

- Remove XmlService classloader fallback (extracted to PR #12237)
- Use MavenModelVersion to compute the minimum model version
  instead of hardcoding 4.0.0 as the fallback
- Align namespace/schemaLocation format strings with
  TransformerSupport conventions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove super(versionRange) call — AbstractMavenIntegrationTestCase has no String constructor

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Use declared modelVersion for namespace, fall back to MavenModelVersion

MavenModelVersion computes the minimum required version based on
features, but help:effective-pom should preserve the version declared
in the POM. Use model.getModelVersion() first and only fall back to
MavenModelVersion when the version is not explicitly set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Guillaume Nodet <gnodet@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
gnodet added a commit to gnodet/maven that referenced this pull request Jun 13, 2026
…he#12237)

* Add XmlService classloader fallback for ServiceLoader discovery

When the thread context classloader cannot see the XmlService
provider (e.g. in plugin classloaders), fall back to loading
via XmlService's own classloader. This prevents
IllegalStateException("No XmlService implementation found")
in environments where the TCCL is isolated.

Co-authored-by: Arturo Bernal <abernal@apache.org>

* Use import instead of FQCN for Optional

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Arturo Bernal <abernal@apache.org>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
gnodet added a commit to gnodet/maven that referenced this pull request Jun 13, 2026
…om (apache#11742)

* Fix apache#11715: preserve 4.1.0 namespace/schema in help:effective-pom

When generating the effective POM for a modelVersion 4.1.0 project,
preserve the root <project> namespace and schemaLocation as 4.1.0
instead of falling back to 4.0.0.

Add/keep coverage with MavenITgh11715EffectivePomNamespaceTest to
verify the effective POM header contains:
- xmlns http://maven.apache.org/POM/4.1.0
- schemaLocation .../maven-4.1.0.xsd

* Extract XmlService classloader fix and use MavenModelVersion

- Remove XmlService classloader fallback (extracted to PR apache#12237)
- Use MavenModelVersion to compute the minimum model version
  instead of hardcoding 4.0.0 as the fallback
- Align namespace/schemaLocation format strings with
  TransformerSupport conventions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove super(versionRange) call — AbstractMavenIntegrationTestCase has no String constructor

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Use declared modelVersion for namespace, fall back to MavenModelVersion

MavenModelVersion computes the minimum required version based on
features, but help:effective-pom should preserve the version declared
in the POM. Use model.getModelVersion() first and only fall back to
MavenModelVersion when the version is not explicitly set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Guillaume Nodet <gnodet@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
gnodet added a commit to gnodet/maven that referenced this pull request Jun 13, 2026
…om (apache#11742)

* Fix apache#11715: preserve 4.1.0 namespace/schema in help:effective-pom

When generating the effective POM for a modelVersion 4.1.0 project,
preserve the root <project> namespace and schemaLocation as 4.1.0
instead of falling back to 4.0.0.

Add/keep coverage with MavenITgh11715EffectivePomNamespaceTest to
verify the effective POM header contains:
- xmlns http://maven.apache.org/POM/4.1.0
- schemaLocation .../maven-4.1.0.xsd

* Extract XmlService classloader fix and use MavenModelVersion

- Remove XmlService classloader fallback (extracted to PR apache#12237)
- Use MavenModelVersion to compute the minimum model version
  instead of hardcoding 4.0.0 as the fallback
- Align namespace/schemaLocation format strings with
  TransformerSupport conventions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove super(versionRange) call — AbstractMavenIntegrationTestCase has no String constructor

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Use declared modelVersion for namespace, fall back to MavenModelVersion

MavenModelVersion computes the minimum required version based on
features, but help:effective-pom should preserve the version declared
in the POM. Use model.getModelVersion() first and only fall back to
MavenModelVersion when the version is not explicitly set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Guillaume Nodet <gnodet@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
gnodet added a commit that referenced this pull request Jun 13, 2026
…2255)

* Fix #11715: preserve 4.1.0 namespace/schema in help:effective-pom

When generating the effective POM for a modelVersion 4.1.0 project,
preserve the root <project> namespace and schemaLocation as 4.1.0
instead of falling back to 4.0.0.

Add/keep coverage with MavenITgh11715EffectivePomNamespaceTest to
verify the effective POM header contains:
- xmlns http://maven.apache.org/POM/4.1.0
- schemaLocation .../maven-4.1.0.xsd

* Extract XmlService classloader fix and use MavenModelVersion

- Remove XmlService classloader fallback (extracted to PR #12237)
- Use MavenModelVersion to compute the minimum model version
  instead of hardcoding 4.0.0 as the fallback
- Align namespace/schemaLocation format strings with
  TransformerSupport conventions



* Remove super(versionRange) call — AbstractMavenIntegrationTestCase has no String constructor



* Use declared modelVersion for namespace, fall back to MavenModelVersion

MavenModelVersion computes the minimum required version based on
features, but help:effective-pom should preserve the version declared
in the POM. Use model.getModelVersion() first and only fall back to
MavenModelVersion when the version is not explicitly set.



---------

Co-authored-by: Arturo Bernal <abernal@apache.org>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet gnodet added the bug Something isn't working label Jun 16, 2026
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.

3 participants