apache/maven · error · IllegalArgumentException

Unsupported class-loading strategy '{}'. Supported values ar

Error message

Unsupported class-loading strategy '{}'. Supported values are: parent-first, plugin and self-first

What it means

When loading a core extension from .mvn/extensions.xml, BootstrapCoreExtensionManager builds a class realm according to the extension's <classLoadingStrategy> element. Only 'parent-first', 'plugin', and 'self-first' are recognized; anything else throws IllegalArgumentException while bootstrapping the extension, before the build starts. The element is optional — the model defaults to 'self-first' (CoreExtension.java), so this error always means an explicitly written, invalid value.

Source

Thrown at compat/maven-embedder/src/main/java/org/apache/maven/cli/internal/BootstrapCoreExtensionManager.java:185

        return Collections.unmodifiableList(extensions);
    }

    private CoreExtensionEntry createExtension(CoreExtension extension, List<Artifact> artifacts) throws Exception {
        String realmId = "coreExtension>" + extension.getGroupId() + ":" + extension.getArtifactId() + ":"
                + extension.getVersion();
        final ClassRealm realm = classWorld.newRealm(realmId, null);
        Set<String> providedArtifacts = Collections.emptySet();
        String classLoadingStrategy = extension.getClassLoadingStrategy();
        if (STRATEGY_PARENT_FIRST.equals(classLoadingStrategy)) {
            realm.importFrom(parentRealm, "");
        } else if (STRATEGY_PLUGIN.equals(classLoadingStrategy)) {
            coreExports.getExportedPackages().forEach((p, cl) -> realm.importFrom(cl, p));
            providedArtifacts = coreExports.getExportedArtifacts();
        } else if (STRATEGY_SELF_FIRST.equals(classLoadingStrategy)) {
            realm.setParentRealm(parentRealm);
        } else {
            throw new IllegalArgumentException("Unsupported class-loading strategy '"
                    + classLoadingStrategy + "'. Supported values are: " + STRATEGY_PARENT_FIRST
                    + ", " + STRATEGY_PLUGIN + " and " + STRATEGY_SELF_FIRST);
        }
        log.debug("Populating class realm {}", realm.getId());
        for (Artifact artifact : artifacts) {
            String id = artifact.getGroupId() + ":" + artifact.getArtifactId();
            if (providedArtifacts.contains(id)) {
                log.debug("  Excluded {}", id);
            } else {
                File file = artifact.getFile();
                log.debug("  Included {} located at {}", id, file);
                realm.addURL(file.toURI().toURL());
            }
        }
        return CoreExtensionEntry.discoverFrom(
                realm,
                Collections.singleton(artifacts.get(0).getFile()),
                extension.getGroupId() + ":" + extension.getArtifactId(),

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Set <classLoadingStrategy> to exactly one of: parent-first, plugin, self-first (lowercase, hyphenated).
  2. If unsure which strategy you need, remove the element entirely — the default self-first applies and the error disappears.
  3. Use 'plugin' only when you intend to reuse the Maven core exported artifacts/packages; otherwise prefer the default.
  4. Re-run with mvn -X to confirm the extension realm builds and the strategy is accepted.

Example fix

<!-- before (.mvn/extensions.xml) -->
<extension>
  <groupId>org.example</groupId><artifactId>ext</artifactId><version>1.0</version>
  <classLoadingStrategy>parentFirst</classLoadingStrategy>
</extension>

<!-- after -->
<extension>
  <groupId>org.example</groupId><artifactId>ext</artifactId><version>1.0</version>
  <classLoadingStrategy>parent-first</classLoadingStrategy>
</extension>
Defensive patterns

Strategy: validation

Validate before calling

// Validate .mvn/extensions.xml before running mvn
private static final Set<String> STRATEGIES = Set.of("parent-first", "plugin", "self-first");
var doc = javax.xml.parsers.DocumentBuilderFactory.newInstance()
        .newDocumentBuilder().parse(Path.of(".mvn/extensions.xml").toFile());
var nodes = doc.getElementsByTagName("classLoadingStrategy");
for (int i = 0; i < nodes.getLength(); i++) {
    String v = nodes.item(i).getTextContent().trim();
    if (!STRATEGIES.contains(v)) {
        throw new IllegalArgumentException("Bad classLoadingStrategy '" + v + "' in extensions.xml");
    }
}

Try / catch

try {
    cli.doMain(args, workingDir, ...);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Unsupported class-loading strategy")) {
        // fix or strip the <classLoadingStrategy> element (default self-first) and retry
    }
    throw e;
}

Prevention

When it happens

Trigger: Editing .mvn/extensions.xml and typing <classLoadingStrategy>parent_first</classLoadingStrategy> (underscore instead of dash), 'parentFirst' (camelCase), ' plugin' (leading/trailing whitespace is trimmed by the reader, but inner spaces remain invalid), or a value copied from unrelated classloader documentation. The check happens during core-extension bootstrap for every build in that project.

Common situations: Hand-editing .mvn/extensions.xml based on memory or blog posts that use different spellings. Configuration management templating that mangles dashes. Copying from another build tool's realm-strategy vocabulary.

Related errors


AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21). Data as JSON: /api/errors/2e0b7012037e5d7c. Report an issue: GitHub.