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
- 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
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
- 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
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
- A method marked with SchemaCreate in class
- ApproximateUnique needs a sampleSize >= 16 for an…
- ApproximateUnique needs an estimation error between 1%…
- AutoValue builder class
- Can not call prepareRun
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)