{"record":{"id":"cdc7fe283a1bac13","repo":"apple/pkl","slug":"did-not-find-expected-java-class-s-on-the-class","errorCode":null,"errorMessage":"Did not find expected Java class `%s` on the classpath for Pkl class `%s`. Is your generated code up to date?","messagePattern":"Did not find expected Java class `(.+?)` on the classpath for Pkl class `(.+?)`\\. Is your generated code up to date\\?","errorType":"exception","errorClass":"InvalidMappingException","httpStatus":null,"severity":"error","filePath":"pkl-config-java/src/main/java/org/pkl/config/java/mapper/ClassRegistry.java","lineNumber":69,"sourceCode":"\n  private static final String PREFIX = \"org.pkl.config.java.mapper.\";\n\n  private static final Set<String> loadedModules = new HashSet<>();\n\n  private ClassRegistry() {}\n\n  static @Nullable Class<?> get(PClassInfo<?> pklClassInfo) {\n    var pklModuleName = pklClassInfo.getModuleName();\n    var pklClassName = pklClassInfo.getQualifiedName();\n    initClassMappings(pklModuleName);\n    var javaName = classMappings.getProperty(PREFIX + pklClassInfo.getQualifiedName());\n    if (javaName == null) {\n      return null;\n    }\n    try {\n      return Class.forName(javaName);\n    } catch (ClassNotFoundException e) {\n      throw new InvalidMappingException(pklClassName, javaName, e);\n    }\n  }\n\n  private static void initClassMappings(String pklModuleName) {\n    synchronized (lock) {\n      if (loadedModules.contains(pklModuleName)) {\n        return;\n      }\n      loadedModules.add(pklModuleName);\n      var url =\n          ClassRegistry.class.getResourceAsStream(\n              CLASSES_DIRECTORY + \"/\" + IoUtils.encodePath(pklModuleName) + \".properties\");\n      if (url == null) {\n        return;\n      }\n      try {\n        classMappings.load(url);\n      } catch (IOException e) {","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-config-java/src/main/java/org/pkl/config/java/mapper/ClassRegistry.java#L51-L87","documentation":"ClassRegistry maps Pkl class names to the generated Java classes and loads them reflectively with Class.forName. When the registry knows the Pkl class's Java name but the class cannot be found on the classpath, it throws InvalidMappingException asking whether your generated code is up to date. This is a codegen/classpath synchronization failure, not a bad input value.","triggerScenarios":"Decoding/unmapping a Pkl value whose module was generated but whose Java classes (or their containing jar) are not on the runtime classpath; running against a stale build where codegen output was deleted or never compiled.","commonSituations":"Forgetting to run the Pkl code generator (or the maven/gradle task that does) before running the app; the generated sources jar not included as a runtime dependency; package renamed in generated code while a cached registry still expects the old FQN; shaded/ relocated classes breaking Class.forName.","solutions":["Run the code generator for the module so the expected Java class exists and is compiled.","Ensure the jar/module containing the generated classes is on the runtime classpath (check dependency scope, e.g. not test-only).","Compare the javaName in the exception message against your generated sources; fix package/name mismatches.","Clean and rebuild to flush stale compiled classes.","If the mapping is genuinely optional, use the registry lookup that tolerates null instead of get()."],"exampleFix":"// before: generated class missing, registry throws\nClass<?> clazz = ClassRegistry.get().get(\"my.app.GeneratedConfig\");\n// after: generate classes first, then fail fast with context\n// build.gradle: pkl { generateJavaCode from(\"pkl/**/*.pkl\") }\nClass<?> clazz = ClassRegistry.get().get(\"my.app.GeneratedConfig\"); // exists after codegen","handlingStrategy":"validation","validationCode":"// verify generated classes are present at startup\nstatic void verifyMappings(String... pklClassNames) {\n  for (String name : pklClassNames) {\n    if (ClassRegistry.get().get(name) == null) {\n      throw new IllegalStateException(\"missing generated class for \" + name\n          + \"; run the Pkl code generator\");\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  return mapper.map(value, TargetClass.class);\n} catch (InvalidMappingException e) {\n  throw new BuildConfigurationException(\n      \"Generated code missing for \" + e.getPklClassName()\n      + \" (expected \" + e.getJavaClassName() + \"); run codegen and rebuild\", e);\n}","preventionTips":["Wire the Pkl code generator into the build so sources are always generated before compile","Ensure generated-code artifacts are a runtime (not test-only) dependency","After renaming packages in generated code, clean the registry-consuming modules and rebuild","Smoke-test mapping of every Pkl module at application startup"],"tags":["classpath","codegen","reflection","pkl","generated-code"],"backgroundTag":"class-not-found","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}