oracle/graal · error · IllegalStateException
Package %s cannot be imported from multiple loaders
Error message
Package %s cannot be imported from multiple loaders
What it means
Mirroring jdk.internal.loader.Loader.remotePackage: while wiring the module configuration, each remote (parent-layer) package is mapped to the loader that provides it. If the same package would be imported from two different class loaders, the mapping is ambiguous and this IllegalStateException is thrown — JPMS forbids reading the same package from multiple loaders in one configuration.
Source
Thrown at compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccessClassLoader.java:248
for (ModuleDescriptor.Exports e : descriptor.exports()) {
if (!e.isQualified()) {
remotePackage(remotePackageMap, e.source(), loader);
}
}
}
}
}
return Collections.unmodifiableMap(remotePackageMap);
}
/**
* See {@code jdk.internal.loader.Loader#remotePackage}.
*/
private static void remotePackage(Map<String, ClassLoader> map, String pn, ClassLoader loader) {
ClassLoader l = map.putIfAbsent(pn, loader);
if (l != null && l != loader) {
throw new IllegalStateException("Package " + pn + " cannot be imported from multiple loaders");
}
}
/**
* See {@code jdk.internal.loader.Loader#findModuleLayer}.
*/
private static Optional<ModuleLayer> findModuleLayer(ModuleLayer moduleLayer, Configuration cf) {
return SharedSecrets.getJavaLangAccess().layers(moduleLayer) //
.filter(l -> l.configuration() == cf) //
.findAny();
}
/**
* See {@code jdk.internal.loader.Loader#findResource(String mn, String name)}.
*/
@Override
protected URL findResource(String mn, String name) throws IOException {
/* For unnamed module, search for resource in class-path */View on GitHub (pinned to a66e9ccd1d)
Solutions
- Ensure each package is readable from exactly one parent loader: deduplicate shared libraries so they are loaded only in the boot layer or only in the custom layer
- Adjust the parent layer configuration passed to VMAccess so overlapping 'requires' edges are not resolved twice
- Isolate conflicting modules into separate configurations/VMAccess instances instead of one shared layer
Example fix
# before # both boot layer and custom layer provide com.example.api --add-modules com.example.api --module-path custom/ # after # load com.example.api only via boot layer; custom layer requires it, does not re-export # (drop the duplicate from the custom module path)
Defensive patterns
Strategy: validation
Validate before calling
Set<String> seen = new HashSet<>();
for (String pn : localPackages) {
for (ModuleLayer parent : parentLayers) {
ClassLoader cl = parent.findLoader(parent.findModule(pn).orElseThrow().name());
// ensure each remote package maps to exactly one loader
}
} Try / catch
catch (IllegalStateException e) { if (e.getMessage().contains("multiple loaders")) { list parent layers exposing the package; deduplicate libraries; } } Prevention
- Design module layers so each library is loaded by exactly one loader
- Avoid nesting image-build/parent configurations that re-export the same packages
- Document which layer owns shared API packages in multi-layer setups
When it happens
Trigger: The module configuration given to HostVMAccessClassLoader resolves modules that 'requires transitive' the same package through two distinct parent loaders/layers (e.g. boot layer plus an custom parent layer that both expose com.example.api). Thrown during loader construction from remotePackage().
Common situations: Layering multiple module layers where a library is visible through two parent loaders (common in app servers, test frameworks, or nested image-build setups); mixing a custom parent ClassLoader that also loads modules from the boot layer.
Related errors
- Package %s in more than one module
- Could not load Graal NodeClass TYPE field for
- LogFile substitution %s cannot be combined with any other ch
- Set the JVMCI_VERSION_CHECK environment variable to "ignore"
- Unknown argument: %s
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/7aaa233fa649ecbd.
Report an issue: GitHub.