{"record":{"id":"e619eab0c0be88e6","repo":"apple/pkl","slug":"failed-to-invoke-javax-inject-named-value","errorCode":null,"errorMessage":"Failed to invoke `javax.inject.Named.value()`.","messagePattern":"Failed to invoke `javax\\.inject\\.Named\\.value\\(\\)`\\.","errorType":"exception","errorClass":"ConversionException","httpStatus":null,"severity":"error","filePath":"pkl-config-java/src/main/java/org/pkl/config/java/mapper/PObjectToDataObject.java","lineNumber":125,"sourceCode":"\n  private static @Nullable String getParameterName(Parameter parameter) {\n    if (parameter.isNamePresent()) {\n      return parameter.getName();\n    }\n\n    Named named = getAnnotation(parameter, Named.class);\n    if (named != null) {\n      return named.value();\n    }\n\n    if (javaxInjectNamedClass != null) {\n      assert javaxInjectNamedValueMethod != null;\n      var ann = getAnnotation(parameter, javaxInjectNamedClass);\n      if (ann != null) {\n        try {\n          return (String) javaxInjectNamedValueMethod.invoke(ann);\n        } catch (IllegalAccessException | InvocationTargetException e) {\n          throw new ConversionException(\"Failed to invoke `javax.inject.Named.value()`.\", e);\n        }\n      }\n    }\n\n    return null;\n  }\n\n  private static @Nullable <T extends Annotation> T getAnnotation(\n      Constructor<?> constructor, Class<T> annotationClass) {\n    try {\n      return constructor.getAnnotation(annotationClass);\n    } catch (IndexOutOfBoundsException e) {\n      // workaround for https://bugs.openjdk.java.net/browse/JDK-8025806\n      return null;\n    }\n  }\n\n  private static @Nullable <T extends Annotation> T getAnnotation(","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-config-java/src/main/java/org/pkl/config/java/mapper/PObjectToDataObject.java#L107-L143","documentation":"pkl-config-java maps Pkl objects to Java data objects via constructors. To resolve constructor parameter names, it falls back to the javax.inject @Named annotation when parameter names aren't retained in bytecode. This error is thrown when reflectively invoking the annotation's value() method fails via IllegalAccessException or InvocationTargetException, so the library cannot determine the parameter name.","triggerScenarios":"Calling Converter.convert on a Pkl Composite whose target Java class has a constructor parameter annotated with javax.inject.@Named, and Method.invoke on the annotation's value() member throws — e.g. the annotation proxy rejects access, the annotation instance is corrupt, or its value() resolver throws InvocationTargetException (nested initializer failure).","commonSituations":"Runtime environments with restricted reflection (custom class loaders, modules closing javax.inject package); classpath conflicts where an incompatible/duplicate javax.inject jar provides a broken @Named; annotation-processed code where the annotation target is inconsistent with the compiled bytecode.","solutions":["Compile with -parameters (or keep the source of parameter names, e.g. Maven maven-compiler-plugin <parameters>true</parameters>) so getParameterName never needs the @Named fallback.","Check the classpath for conflicting javax.inject artifacts and use a single, standard version (javax.inject:javax.inject:1 or jakarta.inject equivalent).","Verify module accessibility: if using JPMS, open/exports the package containing the annotation to pkl-config-java.","If caught as a ConversionException, inspect the cause (IllegalAccessException vs InvocationTargetException) to pinpoint the reflective failure."],"exampleFix":"// before: names resolved via fragile reflective annotation fallback\n<artifactId>maven-compiler-plugin</artifactId>\n<configuration><!-- no --parameters --></configuration>\n\n// after\n<artifactId>maven-compiler-plugin</artifactId>\n<configuration>\n  <parameters>true</parameters>\n</configuration>","handlingStrategy":"validation","validationCode":"// ensure parameter names are resolvable before converting\nboolean namesResolvable(Constructor<?> ctor) {\n  for (Parameter p : ctor.getParameters()) {\n    if (p.isNamePresent()) continue;\n    if (p.getAnnotation(Named.class) != null) continue;\n    if (p.getAnnotation(javax.inject.Named.class) != null) continue;\n    return false;\n  }\n  return true;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Compile with javac -parameters so annotation fallback is never needed","Keep exactly one javax.inject artifact on the classpath","Test reflective conversion of data classes in CI on the target JDK","If using JPMS, open annotation packages to reflective access"],"tags":["reflection","annotation-processing","constructor-mapping","java"],"backgroundTag":"internal-invariant-violation","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}