apache/beam · error · RuntimeException

Unable to generate a have for hasMethod '%s'

Error message

Unable to generate a have for hasMethod '%s'

What it means

JavaBeanUtils.createHaver generates a dynamic FieldValueHaver for a boolean 'has' method of a Java bean. If instantiating the generated class via its reflective no-arg constructor throws InstantiationException, IllegalAccessException, InvocationTargetException, or NoSuchMethodException, this RuntimeException is thrown with the offending hasMethod name.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/JavaBeanUtils.java:304

      Class<ObjectT> clazz, Method hasMethod) {
    DynamicType.Builder<FieldValueHaver<ObjectT>> builder =
        ByteBuddyUtils.subclassHaverInterface(BYTE_BUDDY, clazz);
    builder = implementHaverMethods(builder, hasMethod);
    try {
      return builder
          .visit(new AsmVisitorWrapper.ForDeclaredMethods().writerFlags(ClassWriter.COMPUTE_FRAMES))
          .make()
          .load(
              ReflectHelpers.findClassLoader(clazz.getClassLoader()),
              getClassLoadingStrategy(clazz))
          .getLoaded()
          .getDeclaredConstructor()
          .newInstance();
    } catch (InstantiationException
        | IllegalAccessException
        | InvocationTargetException
        | NoSuchMethodException e) {
      throw new RuntimeException("Unable to generate a have for hasMethod '" + hasMethod + "'", e);
    }
  }

  private static <ObjectT> DynamicType.Builder<FieldValueHaver<ObjectT>> implementHaverMethods(
      DynamicType.Builder<FieldValueHaver<ObjectT>> builder, Method hasMethod) {
    return builder
        .method(ElementMatchers.named("name"))
        .intercept(FixedValue.reference(hasMethod.getName()))
        .method(ElementMatchers.named("has"))
        .intercept(new InvokeHaverInstruction(hasMethod));
  }

  // The list of constructors for a class is cached, so we only create the classes the first time
  // getConstructor is called.
  public static final Map<TypeDescriptorWithSchema<?>, SchemaUserTypeCreator> CACHED_CREATORS =
      Maps.newConcurrentMap();

  public static SchemaUserTypeCreator getConstructorCreator(

View on GitHub (pinned to 12126d8942)

Solutions

  1. Make the bean a concrete public class (static nested class if nested) with a public no-arg constructor
  2. Confirm the has-method is on a concrete class, not an interface or abstract class
  3. Inspect the suppressed/cause exception for the precise reflective failure
  4. Simplify to a top-level public class if classloader visibility is the blocker

Example fix

// before
public class Outer {
  class Inner { public boolean hasValue() { return true; } }
}
// after
public class Outer {
  public static class Inner { public boolean hasValue() { return true; } }
}
Defensive patterns

Strategy: validation

Validate before calling

static void checkBeanHaver(Class<?> c) {
  if (c.isInterface() || java.lang.reflect.Modifier.isAbstract(c.getModifiers()))
    throw new IllegalArgumentException(c + " must be a concrete class");
  try { c.getDeclaredConstructor(); }
  catch (NoSuchMethodException e) { throw new IllegalArgumentException(c + " lacks a no-arg constructor", e); }
}

Type guard

static boolean isConcretePublic(Class<?> c) {
  return !c.isInterface() && java.lang.reflect.Modifier.isPublic(c.getModifiers())
      && !java.lang.reflect.Modifier.isAbstract(c.getModifiers());
}

Try / catch

try {
  havers = JavaBeanUtils.getHavers(MyBean.class, schema, options);
} catch (RuntimeException e) {
  throw new IllegalStateException("Haver generation failed for hasMethod '" + e.getMessage() + "'", e);
}

Prevention

When it happens

Trigger: Calling JavaBeanUtils.getHavers/createHaver for a bean whose has-method's declaring class cannot be reflectively instantiated — e.g. the bean class is abstract, has no accessible no-arg constructor, or the generated proxy cannot be constructed in the current classloader.

Common situations: Schema-registered JavaBeans that are nested non-static inner classes (implicit constructor params), beans with package-private visibility, or has-methods on abstract base classes.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/dd3af2c2c71da49d. Report an issue: GitHub.