{"record":{"id":"80d1a9f02b1b41ab","repo":"apache/maven","slug":"nthere-can-only-be-one-user-supplied-configuratio","errorCode":null,"errorMessage":"%nThere can only be one user supplied ConfigurationProcessor, there are %s:%n%n","messagePattern":"%nThere can only be one user supplied ConfigurationProcessor, there are (.+?):%n%n","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"compat/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java","lineNumber":1229,"sourceCode":"                    configurationProcessor.process(cliRequest);\n                }\n            }\n        } else if (userSuppliedConfigurationProcessorCount > 1) {\n            //\n            // There are too many ConfigurationProcessors so we don't know which one to run so report the error.\n            //\n            StringBuilder sb = new StringBuilder(String.format(\n                    \"%nThere can only be one user supplied ConfigurationProcessor, there are %s:%n%n\",\n                    userSuppliedConfigurationProcessorCount));\n            for (Entry<String, ConfigurationProcessor> entry : configurationProcessors.entrySet()) {\n                String hint = entry.getKey();\n                if (!hint.equals(SettingsXmlConfigurationProcessor.HINT)) {\n                    ConfigurationProcessor configurationProcessor = entry.getValue();\n                    sb.append(String.format(\n                            \"%s%n\", configurationProcessor.getClass().getName()));\n                }\n            }\n            throw new Exception(sb.toString());\n        }\n    }\n\n    void toolchains(CliRequest cliRequest) throws Exception {\n        File userToolchainsFile = null;\n\n        if (cliRequest.commandLine.hasOption(CLIManager.ALTERNATE_USER_TOOLCHAINS)) {\n            userToolchainsFile = new File(cliRequest.commandLine.getOptionValue(CLIManager.ALTERNATE_USER_TOOLCHAINS));\n            userToolchainsFile = ResolveFile.resolveFile(userToolchainsFile, cliRequest.workingDirectory);\n\n            if (!userToolchainsFile.isFile()) {\n                throw new FileNotFoundException(\n                        \"The specified user toolchains file does not exist: \" + userToolchainsFile);\n            }\n        } else {\n            String userToolchainsFileStr = cliRequest.getUserProperties().getProperty(Constants.MAVEN_USER_TOOLCHAINS);\n            if (userToolchainsFileStr != null) {\n                userToolchainsFile = new File(userToolchainsFileStr);","sourceCodeStart":1211,"sourceCodeEnd":1247,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/compat/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java#L1211-L1247","documentation":"During CLI configuration, Maven scans the (Plexus/JSR-330) container for ConfigurationProcessor components. Exactly one non-default processor may exist besides the built-in 'settingsxml' one (SettingsXmlConfigurationProcessor). If two or more user-supplied processors are discovered, Maven cannot decide which to run and throws a plain Exception whose message counts them and lists each offending implementation class name. This only happens when embedding MavenCli or assembling a custom Maven distribution — a stock mvn install has exactly one.","triggerScenarios":"Launching MavenCli/MavenCliRequest programmatically with a classpath containing two ConfigurationProcessor implementations (each registered via Plexus component descriptors or javax.inject @Named). Adding a custom processor project while a third-party dependency (another extension or integrator jar) already ships one. Two versions of the same processor jar ending up on the classpath.","commonSituations":"Companies embedding Maven in build services/IDEs adding their own ConfigurationProcessor, then pulling a dependency that also contains one. Custom Maven distributions (tarballs with extra libs in lib/) that accidentally bundle both a processor and a fat jar embedding another. Duplicate classes after shading/merging jars.","solutions":["Read the class names listed in the exception message; identify which jar ships each one.","Remove or exclude the extra implementation (Maven dependency exclusion, or delete the duplicate jar from the distribution's lib directory).","If both processors are needed, consolidate them into a single implementation that chains the logic, keeping one component.","Verify classpath hygiene: mvn dependency:tree in the embedding project or unzip -l the suspect jars to confirm exactly one ConfigurationProcessor remains."],"exampleFix":"<!-- before: two processors on classpath -->\n<dependency>\n  <groupId>corp</groupId><artifactId>corp-maven-processor</artifactId>\n</dependency>\n<dependency>\n  <groupId>vendor</groupId><artifactId>vendor-build-extensions</artifactId>\n  <!-- also contains a ConfigurationProcessor -->\n</dependency>\n\n<!-- after: exclude the duplicate -->\n<dependency>\n  <groupId>vendor</groupId><artifactId>vendor-build-extensions</artifactId>\n  <exclusions>\n    <exclusion>\n      <groupId>vendor</groupId><artifactId>vendor-processor</artifactId>\n    </exclusion>\n  </exclusions>\n</dependency>","handlingStrategy":"validation","validationCode":"// Embedder startup check before MavenCli.doMain\nList<ConfigurationProcessor> processors = container.lookupList(ConfigurationProcessor.class);\nlong userSupplied = processors.stream()\n        .filter(p -> !SettingsXmlConfigurationProcessor.HINT.equals(roleHintOf(p)))\n        .count();\nif (userSupplied > 1) {\n    throw new IllegalStateException(\"Multiple ConfigurationProcessors on classpath: \"\n        + processors.stream().map(p -> p.getClass().getName()).collect(Collectors.joining(\", \")));\n}","typeGuard":null,"tryCatchPattern":"try {\n    cli.doMain(args, ...);\n} catch (Exception e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"There can only be one user supplied ConfigurationProcessor\")) {\n        // parse listed class names, fail with actionable guidance for the distribution owner\n    }\n    throw e;\n}","preventionTips":["In embedding projects, add a test that asserts exactly one non-default ConfigurationProcessor is discovered on the runtime classpath.","Review dependency trees before adding integrator jars to a custom distribution; exclude duplicate components explicitly.","Never bundle two versions of the same processor jar; let Maven's lib directory contain a single copy."],"tags":["maven","embedder","plexus","dependency-injection","duplicate-component","classpath"],"backgroundTag":"duplicate-service-implementation","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}