apple/pkl · error · ConversionException
Error accessing constructor of class `%s`.
Error message
Error accessing constructor of class `%s`.
What it means
When PMapToMap tries to obtain a MethodHandle for the target Map class's constructors via MethodHandles.Lookup.findConstructor, an IllegalAccessException means the constructor exists but is not accessible from PMapToMap's lookup context (e.g. the class or constructor is private/package-private and not opened to this package). The library rethrows it as this ConversionException at either lookup site (the (int,float) constructor lookup or the default-constructor lookup).
Source
Thrown at pkl-config-java/src/main/java/org/pkl/config/java/mapper/PMapToMap.java:86
});
} catch (NoSuchMethodException e2) {
try {
// default constructor
var ctor0 = lookup.findConstructor(clazz, MethodType.methodType(void.class));
return Optional.of(
length -> {
try {
//noinspection unchecked
return (Map<K, V>) ctor0.invoke();
} catch (Throwable t) {
throw new ConversionException(
String.format("Error invoking constructor of class `%s`.", clazz), t);
}
});
} catch (NoSuchMethodException e0) {
return Optional.empty();
} catch (IllegalAccessException e) {
throw new ConversionException(
String.format("Error accessing constructor of class `%s`.", clazz), e);
}
} catch (IllegalAccessException e) {
throw new ConversionException(
String.format("Error accessing constructor of class `%s`.", clazz), e);
}
}
private static class ConverterImpl<K, V> implements Converter<Map<Object, Object>, Map<K, V>> {
private final Function<Integer, Map<K, V>> targetInstantiator;
private final Type targetKeyType;
private final Type targetValueType;
private PClassInfo<Object> cachedKeyType = PClassInfo.Unavailable;
private @Nullable Converter<Object, K> cachedKeyConverter;
private PClassInfo<Object> cachedValueType = PClassInfo.Unavailable;
private @Nullable Converter<Object, V> cachedValueConverter;View on GitHub (pinned to f3efcbfc9b)
Solutions
- Make the target Map class and the constructor used public.
- If the class is in your own JPMS module, add `opens your.package;` (or `opens your.package to org.pkl.config.java;`) in module-info.java so MethodHandles.Lookup can access the constructor.
- Use a public, standard Map implementation (HashMap, LinkedHashMap) as the conversion target.
- If targeting JDK internal map types, switch to a supported public class — strong encapsulation cannot be bypassed without unsafe flags.
Example fix
// before (module-info.java)
module my.app { }
// after
module my.app { opens my.collections; }
// and/or: public class InternalMap<K,V> extends LinkedHashMap<K,V> { public InternalMap() {} }
Defensive patterns
Strategy: validation
Validate before calling
// Check accessibility from the mapper's perspective before converting:
static boolean isAccessibleForLookup(Class<?> c) {
int mods = c.getModifiers();
return java.lang.reflect.Modifier.isPublic(mods)
&& (c.getModule().isOpen(c.getPackageName(), PMapToMapAccessibleProbe.class.getModule())
|| !c.getModule().isNamed());
} Type guard
static boolean isPublicMapTarget(Type t) {
Class<?> c = (t instanceof Class<?>) ? (Class<?>) t : (Class<?>) ((ParameterizedType) t).getRawType();
return java.lang.reflect.Modifier.isPublic(c.getModifiers()) && Map.class.isAssignableFrom(c);
} Try / catch
try {
Map<String, Object> result = valueRenderer.render(pValue, targetType);
} catch (ConversionException e) {
if (e.getMessage() != null && e.getMessage().contains("Error accessing constructor")) {
log.warn(targetType + " not accessible to mapper; using HashMap instead");
Map<String, Object> result = new java.util.HashMap<>(); // fallback
} else throw e;
} Prevention
- Make conversion-target classes and their constructors public.
- In JPMS modules, `opens` every package holding mapping-target classes.
- Avoid package-private or private nested Map classes as conversion targets.
- Test conversions on JPMS classpath setups matching production (module path vs classpath changes accessibility).
When it happens
Trigger: Mapping a Pkl Map to a Map subtype whose constructors are private, package-private, or whose declaring class is in a non-opened module/package, e.g. converting to a package-private `InternalMap` class from another package via `ValueRenderer.render(value, InternalMap.class)`.
Common situations: Java 9+ strong encapsulation: targeting classes in another module (e.g. JDK internals or an unopened library module); package-private custom map classes in a different package; builder-pattern classes that hide constructors as private.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Error accessing constructor `%s`.
- Error accessing constructor of class `%s`.
- Error invoking constructor of class `%s`.
- JavaType token must be parameterized.
- Error invoking constructor of class `%s`.
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/45cc631c9ab820b4.
Report an issue: GitHub.