apache/flink · error · RuntimeException
Could not initialize comparator {}
Error message
Could not initialize comparator {} What it means
SqlTimeTypeInfo.instantiateComparator reflectively builds the SQL-time comparator (Date, Time, Timestamp) via comparatorClass.getConstructor(boolean.class).newInstance(ascending). If the comparator class lacks the public boolean constructor or instantiation fails, a RuntimeException names the comparator class. This is the same reflection contract as BasicTypeInfo/LocalTimeTypeInfo, applied to java.sql time types.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/common/typeinfo/SqlTimeTypeInfo.java:162
return false;
}
}
@Override
public String toString() {
return clazz.getSimpleName();
}
// --------------------------------------------------------------------------------------------
private static <X> TypeComparator<X> instantiateComparator(
Class<? extends TypeComparator<X>> comparatorClass, boolean ascendingOrder) {
try {
Constructor<? extends TypeComparator<X>> constructor =
comparatorClass.getConstructor(boolean.class);
return constructor.newInstance(ascendingOrder);
} catch (Exception e) {
throw new RuntimeException(
"Could not initialize comparator " + comparatorClass.getName(), e);
}
}
@SuppressWarnings("unchecked")
public static <X> SqlTimeTypeInfo<X> getInfoFor(Class<X> type) {
checkNotNull(type);
if (type == Date.class) {
return (SqlTimeTypeInfo<X>) DATE;
} else if (type == Time.class) {
return (SqlTimeTypeInfo<X>) TIME;
} else if (type == Timestamp.class) {
return (SqlTimeTypeInfo<X>) TIMESTAMP;
}
return null;
}
}View on GitHub (pinned to 2f3c205e92)
Solutions
- Ensure the comparator class for SQL-time types exposes a public constructor accepting a single boolean.
- Avoid overriding SqlTimeTypeInfo/comparator classes; rely on the built-in implementations.
- On restricted JDKs, add the appropriate --add-opens for the comparator package.
Example fix
// before: custom comparator missing boolean constructor
// after: use built-in SqlTimeTypeInfo for Date/Time/Timestamp;
// or ensure: public MyComparator(boolean ascending) { ... } Defensive patterns
Strategy: type-guard
Validate before calling
try {
comparatorClass.getConstructor(boolean.class);
} catch (NoSuchMethodException e) {
throw new IllegalStateException(
comparatorClass + " must have a public (boolean) constructor", e);
} Type guard
static boolean hasBooleanCtor(Class<? extends TypeComparator<?>> c) {
try { c.getConstructor(boolean.class); return true; }
catch (NoSuchMethodException e) { return false; }
} Try / catch
try {
return SqlTimeTypeInfo.instantiateComparator(clazz, asc);
} catch (RuntimeException e) {
throw new IllegalStateException(
"SqlTime comparator " + clazz + " misconfigured", e);
} Prevention
- Use the built-in SqlTimeTypeInfo for Date/Time/Timestamp.
- If forking, add a reflection test for the comparator's boolean constructor.
- On strict JDKs, add --add-opens for the comparator package.
When it happens
Trigger: A custom SqlTimeTypeInfo with a comparatorClass missing the (boolean) constructor; reflective access blocked by JDK settings; comparator class corrupted or abstract in a forked build.
Common situations: Forking Flink and altering the SQL-time comparators; strict module path blocking reflective construction; classpath corruption loading a partial comparator class; migrating between JDK versions that tighten reflection.
Related errors
- Could not initialize basic comparator {}
- Could not initialize comparator {}
- Could not initialize primitive {} array comparator.
- The type {} cannot be used as a key.
- SQL time type expected.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/e6dbf220e50e1dd5.
Report an issue: GitHub.