apple/pkl · error · ConversionException

Error accessing constructor of class `%s`.

Error message

Error accessing constructor of class `%s`.

What it means

Thrown by PCollectionToCollection.createInstantiator when the reflective lookup machinery itself fails: `clazz.getConstructors()` (or equivalent) threw IllegalAccessException, meaning the class or its constructors are not accessible to the caller (non-public class, restrictive module/JPMS access, or a security manager). Wrapped in a ConversionException with the target class name.

Source

Thrown at pkl-config-java/src/main/java/org/pkl/config/java/mapper/PCollectionToCollection.java:99

            // default constructor
            var ctor0 = lookup.findConstructor(clazz, MethodType.methodType(void.class));
            return Optional.of(
                length -> {
                  try {
                    //noinspection unchecked
                    return (Collection<T>) 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);
    }
  }

  private static class ConverterImpl<T> implements Converter<Collection<Object>, Collection<T>> {
    private final Function<Integer, Collection<T>> targetInstantiator;
    private final Type targetElementType;

    private PClassInfo<Object> cachedElementType = PClassInfo.Unavailable;
    private @Nullable Converter<Object, T> cachedConverter;

    private ConverterImpl(
        Function<Integer, Collection<T>> targetInstantiator, Type targetElementType) {
      this.targetInstantiator = targetInstantiator;
      this.targetElementType = targetElementType;
    }

    @Override

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Make the target collection class and its constructors public.
  2. With JPMS, add `opens <package>` (or `exports <package>`) for the target class's package in module-info.java, or run with `--add-opens <module>/<package>=ALL-UNNAMED`.
  3. Map to a standard public collection type (ArrayList, HashSet, HashMap) instead of the restricted class.
  4. Register a custom Converter for the type to bypass reflective constructor access entirely.

Example fix

// before (module-info.java)
module app { }
// after (module-info.java)
module app { opens com.example.collections; }
Defensive patterns

Strategy: try-catch

Validate before calling

try { targetClass.getConstructors(); } catch (SecurityException | java.lang.reflect.InaccessibleObjectException e) { throw new IllegalStateException("Target collection class is not accessible to pkl-config-java: " + targetClass); }

Type guard

static boolean isReflectivelyAccessible(Class<?> c) { return java.lang.reflect.Modifier.isPublic(c.getModifiers()); }

Try / catch

try { MyConfig cfg = mapper.map(module, MyConfig.class); } catch (ConversionException e) { throw new IllegalStateException("Make " + e.getMessage() + " public and JPMS-accessible (add 'opens' in module-info.java)", e.getCause()); }

Prevention

When it happens

Trigger: Mapping a Pkl collection to a package-private or non-public collection class, or to a class in a closed Java module that does not export/opens its package to the pkl-config-java module, so `getConstructors()` cannot expose them.

Common situations: Custom collection classes declared package-private; applications using JPMS (module-info.java) without `opens`/`exports` for the package containing the target class; security-manager-restricted environments.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/45902acdb593757e. Report an issue: GitHub.