{"record":{"id":"056964945a568102","repo":"apache/beam","slug":"cannot-register-coder-does-not-have-an-accessible-method","errorCode":null,"errorMessage":"cannot register Coder : does not have an accessible method named 'of' with  arguments of Coder type","messagePattern":"cannot register Coder : does not have an accessible method named 'of' with  arguments of Coder type","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/coders/CoderProviders.java","lineNumber":115,"sourceCode":"      this.factoryMethod = getFactoryMethod(coderClazz);\n    }\n\n    /**\n     * Returns the static {@code of} constructor method on {@code coderClazz} if it exists. It is\n     * assumed to have one {@link Coder} parameter for each type parameter of {@code coderClazz}.\n     */\n    private static Method getFactoryMethod(Class<?> coderClazz) {\n      Method factoryMethodCandidate;\n\n      // Find the static factory method of coderClazz named 'of' with\n      // the appropriate number of type parameters.\n      int numTypeParameters = coderClazz.getTypeParameters().length;\n      Class<?>[] factoryMethodArgTypes = new Class<?>[numTypeParameters];\n      Arrays.fill(factoryMethodArgTypes, Coder.class);\n      try {\n        factoryMethodCandidate = coderClazz.getDeclaredMethod(\"of\", factoryMethodArgTypes);\n      } catch (NoSuchMethodException | SecurityException exn) {\n        throw new IllegalArgumentException(\n            \"cannot register Coder \"\n                + coderClazz\n                + \": \"\n                + \"does not have an accessible method named 'of' with \"\n                + numTypeParameters\n                + \" arguments of Coder type\",\n            exn);\n      }\n      if (!Modifier.isStatic(factoryMethodCandidate.getModifiers())) {\n        throw new IllegalArgumentException(\n            \"cannot register Coder \"\n                + coderClazz\n                + \": \"\n                + \"method named 'of' with \"\n                + numTypeParameters\n                + \" arguments of Coder type is not static\");\n      }\n      if (!coderClazz.isAssignableFrom(factoryMethodCandidate.getReturnType())) {","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/CoderProviders.java#L97-L133","documentation":"CoderProviders.fromStaticMethods requires the Coder class to declare a method named exactly `of` whose parameter count equals the class's type-parameter count and whose parameters are all of type Coder. getDeclaredMethod throws NoSuchMethodException (or SecurityException blocks lookup) when no such method exists, and this IllegalArgumentException is thrown at registration time. Registration fails immediately; the provider is never usable.","triggerScenarios":"Passing a coderClazz to CoderProviders.fromStaticMethods(rawType, coderClazz) where the class has no `static Coder<T> of(Coder<?>, ...)` method matching its type-parameter count — e.g. `of` takes different argument types (TypeDescriptor, List<Coder<?>>), the factory is named `of` with wrong arity, or the class relies on a constructor instead of a static factory. Also thrown if a SecurityManager denies access via getDeclaredMethod.","commonSituations":"Registering a Coder whose factory signature follows an older Beam convention (e.g. of(TypeDescriptor, List)) rather than one Coder arg per type parameter; generic Coder classes with zero type parameters that nonetheless declare of(List<Coder<?>>); running under a SecurityManager or Java module restrictions that block reflection.","solutions":["Add or rename a static factory in the Coder class: `public static <T> MyCoder<T> of(Coder<T> componentCoder)` with one Coder parameter per type parameter of the class","If the class's `of` signature cannot match, register the coder via CoderProviders.forCoder(typeDescriptor, coderInstance) instead of fromStaticMethods","Ensure the method is declared on coderClazz itself (getDeclaredMethod does not search superclasses)","Check coderClazz.getTypeParameters(): the arity of `of` must equal it exactly","If a SecurityException is the cause, grant reflection permission or run without a restricting SecurityManager"],"exampleFix":"// before: no matching factory\nclass KVCoder<K, V> extends StructuredCoder<KV<K, V>> {\n  public static KVCoder of(Coder k, List<Coder> rest) { ... }\n}\n// after: one Coder arg per type parameter\nclass KVCoder<K, V> extends StructuredCoder<KV<K, V>> {\n  public static <K, V> KVCoder<K, V> of(Coder<K> keyCoder, Coder<V> valueCoder) { ... }\n}","handlingStrategy":"validation","validationCode":"static boolean hasValidOfFactory(Class<?> coderClazz) {\n  try {\n    Class<?>[] argTypes = new Class<?>[coderClazz.getTypeParameters().length];\n    java.util.Arrays.fill(argTypes, Coder.class);\n    coderClazz.getDeclaredMethod(\"of\", argTypes);\n    return true;\n  } catch (NoSuchMethodException | SecurityException e) {\n    return false;\n  }\n}\n// assert hasValidOfFactory(MyCoder.class) before CoderProviders.fromStaticMethods(...)","typeGuard":"static <T extends Coder<?>> boolean canRegisterFromStaticMethods(Class<T> coderClazz) {\n  try {\n    Class<?>[] argTypes = new Class<?>[coderClazz.getTypeParameters().length];\n    java.util.Arrays.fill(argTypes, Coder.class);\n    return coderClazz.isAssignableFrom(\n        coderClazz.getDeclaredMethod(\"of\", argTypes).getReturnType());\n  } catch (NoSuchMethodException | SecurityException e) { return false; }\n}","tryCatchPattern":"try {\n  CoderProvider provider = CoderProviders.fromStaticMethods(rawType, coderClazz);\n} catch (IllegalArgumentException e) {\n  // registration-time validation failure; fall back to an explicit coder\n  provider = CoderProviders.forCoder(typeDescriptor, coderInstance);\n}","preventionTips":["Give every generic Coder class a static of(Coder, ...) with one arg per type parameter","Remember getDeclaredMethod only sees methods declared on the class itself, not superclasses","Check arity against getTypeParameters().length when copying factory patterns between coders","Use CoderProviders.forCoder when a class has no suitable static factory","Avoid SecurityManager-restricted environments for reflective registration"],"tags":["java","reflection","coders","apache-beam","registration"],"backgroundTag":"missing-required-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}