quarkusio/quarkus · error · IllegalStateException

Module '' has been defined twice, in: and

Error message

Module '' has been defined twice, in:  and 

What it means

While building the modularity model, ModularitySteps.buildModularityModel maps each module name to its ModuleInfo. If two different module descriptors (different resolved artifacts) claim the same module name, the build fails, since a JPMS module name must be unique. Identical duplicates are tolerated; only conflicting definitions throw.

Source

Thrown at extensions/packaging/modular/deployment/src/main/java/io/quarkus/modular/deployment/ModularitySteps.java:418

                                            e.getValue().stream().collect(
                                                    Collectors.toMap(Function.identity(), ignored -> PackageAccess.OPEN))))
                                    .toList());
                        }
                        // tabulate any used JDK modules.
                        mi.dependencies().stream()
                                .map(DependencyInfo::moduleName)
                                .filter(n -> n.startsWith("java.") || n.startsWith("jdk.") || n.startsWith("ibm."))
                                .forEach(usedJdkModuleNames::add);
                        return mi;
                    });
            // Add the module to the index.
            if (modulesByName.containsKey(moduleName)) {
                ModuleInfo existing = modulesByName.get(moduleName);
                if (existing.equals(depModule)) {
                    // no harm; it's just in there twice for some reason
                    continue;
                }
                throw new IllegalStateException("Module '" + moduleName + "' has been defined twice, in: " +
                        depModule.resolvedArtifact() + " and " + existing.resolvedArtifact());
            }
            modulesByName.put(moduleName, depModule);
            // Warn about any split packages (temporary until #44657; then we don't care as much about it).
            depModule.packages().keySet().forEach(pn -> {
                String existing = modulesByPackageTemporary.putIfAbsent(pn, moduleName);
                if (existing != null && !existing.equals(moduleName)) {
                    log.warnf("Package %s is split, in %s and %s", pn, existing, moduleName);
                }
            });
        }

        // Compute the set of extra app module dependencies from ArC component providers.
        // todo: Remove once #52933 is sorted out.
        for (String pn : extraAppModuleDepPackages) {
            String moduleName = modulesByPackageTemporary.get(pn);
            if (moduleName != null) {
                extraDepsMap.computeIfAbsent(appModuleName, ModularitySteps::newMap)

View on GitHub (pinned to e1c734241f)

Solutions

  1. Run mvn dependency:tree and exclude/remove the duplicate artifact providing the conflicting module
  2. Bump or align versions so only one artifact with that module name is on the module path
  3. If you shade/relocate a library, also change its module name in module-info or Automatic-Module-Name
  4. Clean build to ensure stale artifacts are not being reused

Example fix

// before: two jars both declaring module com.example.lib
<dependency>com.example:lib:1.0</dependency>
<dependency>com.example:lib-shaded:1.0</dependency> <!-- same module name -->
// after: exclude the duplicate
<dependency>com.example:lib:1.0</dependency>
Defensive patterns

Strategy: validation

Validate before calling

// detect duplicate module names across artifacts before the build step
Map<String, List<Path>> byName = new HashMap<>();
for (ResolvedDependency d : deps) {
    String name = readModuleName(d); // from module-info or Automatic-Module-Name
    byName.computeIfAbsent(name, k -> new ArrayList<>()).add(d.resolvedArtifact());
}
byName.forEach((name, artifacts) -> {
    if (artifacts.size() > 1) throw new IllegalStateException("Duplicate module '" + name + "': " + artifacts);
});

Try / catch

try {
    buildModularityModel(...);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("defined twice")) {
        throw new IllegalStateException("Duplicate JPMS module name; run mvn dependency:tree and exclude the extra artifact", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Two distinct artifacts on the class/module path both contain module-info with the same module name (e.g. an app module and an old version, or two jars defining the same Automatic-Module-Name/module name).

Common situations: Version conflicts resolved into multiple copies on the module path; a library renamed/repackaged under a new coordinate keeping the same module name; shading a module into another artifact without changing its name.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/13f24994c6e13766. Report an issue: GitHub.