{"record":{"id":"14a74f3bdea840d3","repo":"apache/beam","slug":"set-of-classes-can-t-be-null","errorCode":null,"errorMessage":"set of classes can't be null","messagePattern":"set of classes can't be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/util/common/ReflectHelpers.java","lineNumber":281,"sourceCode":"   * Finds the appropriate {@code ClassLoader} to be used by the {@link ServiceLoader#load} call,\n   * which by default would use the proposed {@code ClassLoader}, which can be null. The fallback is\n   * as follows: context ClassLoader, class ClassLoader and finally the system ClassLoader.\n   */\n  public static ClassLoader findClassLoader(@Nullable final ClassLoader proposed) {\n    ClassLoader classLoader = proposed;\n    if (classLoader == null) {\n      classLoader = ReflectHelpers.class.getClassLoader();\n    }\n    if (classLoader == null) {\n      classLoader = ClassLoader.getSystemClassLoader();\n    }\n    return classLoader;\n  }\n\n  /** Find the common classloader of all these classes. */\n  public static ClassLoader findClassLoader(final Class<?>... classes) {\n    if (classes == null || classes.length == 0) {\n      throw new IllegalArgumentException(\"set of classes can't be null\");\n    }\n    ClassLoader current = null;\n    for (final Class<?> clazz : classes) {\n      final ClassLoader proposed = clazz.getClassLoader();\n      if (proposed == null) {\n        continue;\n      }\n      if (current == null) {\n        current = proposed;\n      } else if (proposed != current && isParent(current, proposed)) {\n        current = proposed;\n      }\n    }\n    return current == null ? ClassLoader.getSystemClassLoader() : current;\n  }\n\n  /**\n   * Finds the appropriate {@code ClassLoader} to be used by the {@link ServiceLoader#load} call,","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/util/common/ReflectHelpers.java#L263-L299","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass at least one class, e.g. the caller's own class: findClassLoader(MyClass.class)","Guard the call site: if the class list is empty, fall back to a default classloader instead of calling findClassLoader","Check upstream code that constructs the class array to see why it is empty"],"exampleFix":"// before\nClassLoader cl = ReflectHelpers.findClassLoader(classes.toArray(new Class<?>[0]));\n// after\nClassLoader cl = classes.isEmpty()\n    ? ReflectHelpers.findClassLoader(MyPipeline.class)\n    : ReflectHelpers.findClassLoader(classes.toArray(new Class<?>[0]));","handlingStrategy":"type-guard","validationCode":"if (classes == null || classes.length == 0) {\n  classes = new Class<?>[] { MyClass.class };\n}\nClassLoader cl = ReflectHelpers.findClassLoader(classes);","typeGuard":"boolean usable(Class<?>[] cs) { return cs != null && cs.length > 0; }","tryCatchPattern":"try {\n  return ReflectHelpers.findClassLoader(classes);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"set of classes\")) {\n    return MyClass.class.getClassLoader(); // sensible default\n  }\n  throw e;\n}","preventionTips":["Never call findClassLoader with an empty varargs list","Default to the calling class's classloader when the candidate list is empty","Test plugin-discovery code paths that build class arrays dynamically"],"tags":["java","reflection","argument-validation"],"backgroundTag":"null-argument","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"}