{"record":{"id":"7c245789daf122cc","repo":"apache/beam","slug":"impossible-state-missing-apply-method-entirely","errorCode":null,"errorMessage":"Impossible state: missing 'apply' method entirely","messagePattern":"Impossible state: missing 'apply' method entirely","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/InferableFunction.java","lineNumber":59,"sourceCode":"\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  }\n\n  public static <InputT, OutputT>\n      InferableFunction<InputT, OutputT> fromProcessFunctionWithOutputType(\n          ProcessFunction<InputT, OutputT> fn, TypeDescriptor<OutputT> outputType) {\n    return new InferableFunctionWithOutputType<>(fn, outputType);\n  }\n","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/InferableFunction.java#L41-L77","documentation":"InferableFunction's no-arg constructor uses reflection to locate the subclass's 'apply' method (declared in the Function interface). If reflection returns NoSuchMethodException, the class cannot even see an apply method, which should be impossible for a well-formed subclass — hence 'impossible state'. This indicates a broken/obfuscated subclass or a reflection failure, and the library wraps it in a RuntimeException.","triggerScenarios":"Instantiating a subclass of InferableFunction via the public no-arg constructor when getMethod(\"apply\") throws NoSuchMethodException — e.g. the subclass does not actually override/declare apply, or bytecode processing/proguard removed or renamed it.","commonSituations":"Custom DoFn mapping functions written as anonymous classes missing the apply override; ProGuard/R8 stripping method names in production builds; class-loading quirks in shaded jars.","solutions":["Ensure the subclass overrides public OutputT apply(InputT input), or pass a ProcessFunction (lambda/method reference) to the protected constructor: new InferableFunction<InputT,OutputT>(x -> ...)","If using ProGuard/R8, add keep rules for the apply method and InferableFunction subclasses","Verify the deployed jar's bytecode matches the source (no stale/obfuscated classes)"],"exampleFix":"// before\nclass MyFn<I, O> extends InferableFunction<I, O> { }\n// after\nclass MyFn<I, O> extends InferableFunction<I, O> {\n  @Override\n  public O apply(I input) { return transform(input); }\n}","handlingStrategy":"type-guard","validationCode":"boolean ok = false;\nfor (Method m : MyFn.class.getMethods()) {\n  if (m.getName().equals(\"apply\") && !m.isSynthetic()) { ok = true; break; }\n}\nif (!ok) throw new IllegalStateException(\"MyFn must override apply\");","typeGuard":"static boolean hasApplyMethod(Class<?> c) {\n  try { c.getMethod(\"apply\", Object.class); return true; }\n  catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try {\n  InferableFunction<I, O> fn = new MyFn<>();\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Impossible state\")) {\n    // fall back to explicit ProcessFunction\n    fn = new InferableFunction<>(input -> transform(input));\n  } else { throw e; }\n}","preventionTips":["Always override apply() in InferableFunction subclasses","Prefer passing a lambda/ProcessFunction to the constructor instead of subclassing","Add ProGuard/R8 keep rules for apply methods in production builds"],"tags":["java","reflection","apache-beam"],"backgroundTag":"internal-invariant-violation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}