{"record":{"id":"10c9949c9949574a","repo":"apache/beam","slug":"subclass-of-inferablefunction-must-override-apply-method-or","errorCode":null,"errorMessage":"Subclass of InferableFunction must override 'apply' method or pass a ProcessFunction to the constructor, usually via a lambda or method reference.","messagePattern":"Subclass of InferableFunction must override 'apply' method or pass a ProcessFunction to the constructor, usually via a lambda or method reference\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/InferableFunction.java","lineNumber":52,"sourceCode":"@SuppressWarnings({\n  \"nullness\" // TODO(https://github.com/apache/beam/issues/20497)\n})\npublic abstract class InferableFunction<InputT, OutputT>\n    implements ProcessFunction<InputT, OutputT>, HasDisplayData {\n\n  private final @Nullable ProcessFunction<InputT, OutputT> fn;\n\n  protected InferableFunction() {\n    this.fn = null;\n    // A subclass must override apply if using this constructor. Check that via\n    // reflection.\n    try {\n      Method methodThatMustBeOverridden =\n          InferableFunction.class.getDeclaredMethod(\"apply\", Object.class);\n      Method methodOnSubclass = getClass().getMethod(\"apply\", Object.class);\n\n      if (methodOnSubclass.equals(methodThatMustBeOverridden)) {\n        throw new IllegalStateException(\n            \"Subclass of InferableFunction must override 'apply' method\"\n                + \" or pass a ProcessFunction to the constructor,\"\n                + \" usually via a lambda or method reference.\");\n      }\n\n    } catch (NoSuchMethodException exc) {\n      throw new RuntimeException(\"Impossible state: missing 'apply' method entirely\", exc);\n    }\n  }\n\n  protected InferableFunction(ProcessFunction<InputT, OutputT> fn) {\n    this.fn = fn;\n  }\n\n  @Override\n  public OutputT apply(InputT input) throws Exception {\n    return fn.apply(input);\n  }","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/InferableFunction.java#L34-L70","documentation":"InferableFunction derives type information by reflecting on the subclass's apply(Object) method. If the subclass neither overrides apply nor passes a ProcessFunction/SerializableFunction to the constructor, reflection finds only InferableFunction's own abstract apply, and the constructor throws IllegalStateException because no function body exists to infer types from or invoke.","triggerScenarios":"new InferableFunction<...>() { } with no apply override and no constructor argument; anonymous subclass that only overrides other methods; calling the no-arg protected constructor path without supplying a function.","commonSituations":"Migrating old MapElements/Via code that used anonymous InferableFunction subclasses to lambdas; typos where the method is named Apply or has a different signature so it doesn't override apply(Object); copying boilerplate that left the class body empty.","solutions":["Pass a lambda or method reference to the constructor, e.g. new InferableFunction<InputT, OutputT>(input -> transform(input))","Override apply in the anonymous/derived class: new InferableFunction<InputT, OutputT>() { public OutputT apply(InputT input) {...} }","Prefer the modern replacement: MapElements.via(new SimpleFunction<InputT, OutputT>() {...}) or a lambda with TypeDescriptors","Check the method signature matches exactly apply(Object)-erased, i.e. public OutputT apply(InputT input) with no typos","Catch IllegalStateException at construction time to fail fast with a clearer application-level message"],"exampleFix":"// before\nnew InferableFunction<String, Integer>() { } // no apply override\n// after\nnew InferableFunction<String, Integer>(s -> s.length());","handlingStrategy":"type-guard","validationCode":"if (fn.getClass().getMethod(\"apply\", Object.class).getDeclaringClass() == InferableFunction.class) {\n  throw new IllegalArgumentException(\"Pass a lambda or override apply\");\n}","typeGuard":"static boolean hasApplyOverride(InferableFunction<?, ?> fn) throws NoSuchMethodException {\n  return !fn.getClass()\n      .getMethod(\"apply\", Object.class)\n      .getDeclaringClass()\n      .equals(InferableFunction.class);\n}","tryCatchPattern":"try {\n  InferableFunction<I,O> fn = new InferableFunction<I,O>() { };\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"must override 'apply'\")) { /* supply lambda/override */ }\n  else throw e;\n}","preventionTips":["Prefer lambdas or SimpleFunction over anonymous InferableFunction subclasses","Verify the override signature is exactly apply(Object)-compatible","Replace InferableFunction usages with MapElements.via(new SimpleFunction<>...)"],"tags":["apache-beam","java","reflection","functional","constructor"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}