apache/beam · error · RuntimeException
Cannot find requested QueryPlanner class: ${queryPlannerClas
Error message
Cannot find requested QueryPlanner class: ${queryPlannerClassName} What it means
BeamSqlEnv's planner builder instantiates the QueryPlanner reflectively via Class.forName using the configured planner class name. If the class is not on the classpath, it wraps the ClassNotFoundException in a RuntimeException naming the requested class.
Source
Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/BeamSqlEnv.java:334
ins.getBeamSqlUdfs().forEach(this::addUdf);
ins.getSerializableFunctionUdfs().forEach(this::addUdf);
ins.getUdafs().forEach(this::addUdaf);
});
}
private void addUdfsUdafs(JdbcConnection connection) {
for (Map.Entry<String, Function> functionEntry : functionSet) {
connection.getCurrentSchemaPlus().add(functionEntry.getKey(), functionEntry.getValue());
}
}
private QueryPlanner instantiatePlanner(
JdbcConnection jdbcConnection, Collection<RuleSet> ruleSets) {
Class<?> queryPlannerClass;
try {
queryPlannerClass = Class.forName(queryPlannerClassName);
} catch (ClassNotFoundException exc) {
throw new RuntimeException(
"Cannot find requested QueryPlanner class: " + queryPlannerClassName, exc);
}
// This try/catch kept deliberately tight to ensure that we _only_ catch exceptions due to
// this reflective access.
QueryPlanner.Factory factory;
try {
// See https://github.com/typetools/jdk/pull/235#pullrequestreview-3400922783
@SuppressWarnings("nullness")
Object queryPlannerFactoryObj =
checkStateNotNull(
queryPlannerClass.getField("FACTORY").get(null),
"Static field %s.FACTORY is null. It must be a QueryPlanner.Factory instance.",
queryPlannerClass);
factory = (QueryPlanner.Factory) queryPlannerFactoryObj;
} catch (NoSuchFieldException | IllegalAccessException exc) {
throw new RuntimeException(
String.format(View on GitHub (pinned to 12126d8942)
Solutions
- Verify the class name string matches the fully-qualified planner class exactly
- Add the artifact containing the planner class to the runtime classpath
- Or omit the custom planner to use the default Beam QueryPlanner
- If shading, keep the planner package unshaded or update the configured name to the relocated name
Example fix
// before
builder.setQueryPlannerClassName("org.apache.beam.sql.MyPlanner"); // not on classpath
// after
builder.setQueryPlannerClassName("org.apache.beam.sdk.extensions.sql.impl.planner BeamQueryPlanner");
// (use the exact FQCN: org.apache.beam.sdk.extensions.sql.impl.BeamQueryPlanner) Defensive patterns
Strategy: try-catch
Validate before calling
try { Class.forName(queryPlannerClassName); } catch (ClassNotFoundException e) { /* fail fast with clear message */ } Type guard
boolean plannerClassPresent(String cn) { try { Class.forName(cn); return true; } catch (ClassNotFoundException e) { return false; } } Try / catch
try { env = builder.build(); } catch (RuntimeException e) { if (e.getMessage().contains("Cannot find requested QueryPlanner")) { /* fix classpath/config */ } throw e; } Prevention
- Verify planner artifact is a runtime dependency
- Use exact fully-qualified class names
- Prefer the default planner unless customization is needed
When it happens
Trigger: Setting a custom queryPlannerClassName on BeamSqlEnvBuilder (or JDBC config) whose class is absent from the runtime classpath, then initializing the planner.
Common situations: Shading/relocation removing the planner class, missing dependency jar at runtime, typo in the fully-qualified class name, switching from the default planner without adding the module.
Related errors
- Failed to locate required method ${className}.${methodName}
- Failed to locate ProcessContinuation.stop()
- Failed to locate DefaultGetSize.validateSize()
- Unable to find UserCodeException.wrap
- Could not find class: %s
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/cd682bc92e909e24.
Report an issue: GitHub.