apache/beam · error · IllegalArgumentException

set of classes can't be null

Error message

set of classes can't be null

What it means

findClassLoader (a null-tolerant ClassLoader resolution helper) hit its final fallback and was still left without a loader to return; the guard asserts that the set of classes used to derive a loader cannot be null. The proposed ClassLoader and the classes argument are the inputs at fault — effectively the JVM exposed no usable classloader (bootstrap-loaded context).

Solutions

  1. Pass at least one class, e.g. the caller's own class: findClassLoader(MyClass.class)
  2. Guard the call site: if the class list is empty, fall back to a default classloader instead of calling findClassLoader
  3. Check upstream code that constructs the class array to see why it is empty

Example fix

// before
ClassLoader cl = ReflectHelpers.findClassLoader(classes.toArray(new Class<?>[0]));
// after
ClassLoader cl = classes.isEmpty()
    ? ReflectHelpers.findClassLoader(MyPipeline.class)
    : ReflectHelpers.findClassLoader(classes.toArray(new Class<?>[0]));
Defensive patterns

Strategy: type-guard

Validate before calling

if (classes == null || classes.length == 0) {
  classes = new Class<?>[] { MyClass.class };
}
ClassLoader cl = ReflectHelpers.findClassLoader(classes);

Type guard

boolean usable(Class<?>[] cs) { return cs != null && cs.length > 0; }

Try / catch

try {
  return ReflectHelpers.findClassLoader(classes);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("set of classes")) {
    return MyClass.class.getClassLoader(); // sensible default
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling ReflectHelpers.findClassLoader() with no arguments, or findClassLoader((Class<?>[]) null) — e.g. from reflection-based setup where the class list was built dynamically and came out empty.

Common situations: Plugin/service discovery code whose candidate class list failed to populate; refactoring that dropped the required class arguments; passing a Collection.toArray() of an empty collection.

Related errors


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

Appendix: source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/util/common/ReflectHelpers.java:281

   * Finds the appropriate {@code ClassLoader} to be used by the {@link ServiceLoader#load} call,
   * which by default would use the proposed {@code ClassLoader}, which can be null. The fallback is
   * as follows: context ClassLoader, class ClassLoader and finally the system ClassLoader.
   */
  public static ClassLoader findClassLoader(@Nullable final ClassLoader proposed) {
    ClassLoader classLoader = proposed;
    if (classLoader == null) {
      classLoader = ReflectHelpers.class.getClassLoader();
    }
    if (classLoader == null) {
      classLoader = ClassLoader.getSystemClassLoader();
    }
    return classLoader;
  }

  /** Find the common classloader of all these classes. */
  public static ClassLoader findClassLoader(final Class<?>... classes) {
    if (classes == null || classes.length == 0) {
      throw new IllegalArgumentException("set of classes can't be null");
    }
    ClassLoader current = null;
    for (final Class<?> clazz : classes) {
      final ClassLoader proposed = clazz.getClassLoader();
      if (proposed == null) {
        continue;
      }
      if (current == null) {
        current = proposed;
      } else if (proposed != current && isParent(current, proposed)) {
        current = proposed;
      }
    }
    return current == null ? ClassLoader.getSystemClassLoader() : current;
  }

  /**
   * Finds the appropriate {@code ClassLoader} to be used by the {@link ServiceLoader#load} call,

View on GitHub (pinned to 12126d8942)