apache/beam · error · IllegalStateException

Cannot determine context class

Error message

Cannot determine context class

What it means

Plugin.initContext scans the CDAP plugin class's declared methods to decide which context implementation (batch source, batch sink, or streaming source) to instantiate, matching by method name (e.g., GET_STREAM_METHOD_NAME). When no method matches any known pattern, the loop completes without returning and the method throws IllegalStateException, because the plugin type could not be inferred.

Source

Thrown at sdks/java/io/cdap/src/main/java/org/apache/beam/sdk/io/cdap/Plugin.java:231

    Class<?> contextClass;
    List<Method> methods = new ArrayList<>(Arrays.asList(cdapPluginClass.getDeclaredMethods()));
    Class<?> cdapPluginSuperclass = cdapPluginClass.getSuperclass();
    if (cdapPluginSuperclass != null) {
      methods.addAll(Arrays.asList(cdapPluginSuperclass.getDeclaredMethods()));
    }
    for (Method method : methods) {
      if (method.getName().equals(PREPARE_RUN_METHOD_NAME)) {
        contextClass = method.getParameterTypes()[0];
        if (contextClass.equals(BatchSourceContext.class)) {
          return new BatchSourceContextImpl();
        } else if (contextClass.equals(BatchSinkContext.class)) {
          return new BatchSinkContextImpl();
        }
      } else if (method.getName().equals(GET_STREAM_METHOD_NAME)) {
        return new StreamingSourceContextImpl();
      }
    }
    throw new IllegalStateException("Cannot determine context class");
  }

  /** Gets value of a plugin type. */
  public Boolean isUnbounded() {
    Boolean isUnbounded = null;

    for (Annotation annotation : getPluginClass().getDeclaredAnnotations()) {
      if (annotation.annotationType().equals(io.cdap.cdap.api.annotation.Plugin.class)) {
        String pluginType = ((io.cdap.cdap.api.annotation.Plugin) annotation).type();
        isUnbounded = pluginType != null && pluginType.startsWith("streaming");
      }
    }
    if (isUnbounded == null) {
      throw new IllegalArgumentException("CDAP plugin class must have Plugin annotation!");
    }
    return isUnbounded;
  }

View on GitHub (pinned to 12126d8942)

Solutions

  1. Confirm the plugin class exposes the standard accessor methods the adapter looks for (matching the GET_..._METHOD_NAME constants)
  2. Regenerate/rebuild the plugin from a current CDAP archetype so method naming matches the contract
  3. Check that the plugin was correctly classified as source vs sink before initContext runs
  4. If using obfuscation (ProGuard/minification), keep the plugin accessor method names
Defensive patterns

Strategy: validation

Validate before calling

boolean hasStandardAccessors(Class<?> pluginClass) {
  for (Method m : pluginClass.getDeclaredMethods()) {
    String n = m.getName();
    if (n.contains("Source") || n.contains("Sink")) return true;
  }
  return false;
}

Type guard

static boolean isInitContextSafe(Class<?> c) {
  return java.util.Arrays.stream(c.getDeclaredMethods())
      .map(Method::getName)
      .anyMatch(n -> n.contains("Source") || n.contains("Sink"));
}

Try / catch

try {
  return initContext(cdapPluginClass);
} catch (IllegalStateException e) {
  LOG.error("Plugin {} lacks expected source/sink accessor methods", cdapPluginClass.getName(), e);
  throw e;
}

Prevention

When it happens

Trigger: Invoking initContext (indirectly via the CDAP connector expand path) on a plugin class whose introspected methods do not include the expected source/sink accessor method names — for example a plugin that overrides method names, or a plugin class whose type was misclassified upstream.

Common situations: Using a custom CDAP plugin that deviates from the standard BatchSource/BatchSink method contract; class obfuscation or shading renaming accessor methods; mixing CDAP plugin versions where the expected method names changed.

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/1d19b542021a4701. Report an issue: GitHub.