{"record":{"id":"cd682bc92e909e24","repo":"apache/beam","slug":"cannot-find-requested-queryplanner-class","errorCode":null,"errorMessage":"Cannot find requested QueryPlanner class: ${queryPlannerClassName}","messagePattern":"Cannot find requested QueryPlanner class: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/BeamSqlEnv.java","lineNumber":334,"sourceCode":"                ins.getBeamSqlUdfs().forEach(this::addUdf);\n                ins.getSerializableFunctionUdfs().forEach(this::addUdf);\n                ins.getUdafs().forEach(this::addUdaf);\n              });\n    }\n\n    private void addUdfsUdafs(JdbcConnection connection) {\n      for (Map.Entry<String, Function> functionEntry : functionSet) {\n        connection.getCurrentSchemaPlus().add(functionEntry.getKey(), functionEntry.getValue());\n      }\n    }\n\n    private QueryPlanner instantiatePlanner(\n        JdbcConnection jdbcConnection, Collection<RuleSet> ruleSets) {\n      Class<?> queryPlannerClass;\n      try {\n        queryPlannerClass = Class.forName(queryPlannerClassName);\n      } catch (ClassNotFoundException exc) {\n        throw new RuntimeException(\n            \"Cannot find requested QueryPlanner class: \" + queryPlannerClassName, exc);\n      }\n\n      // This try/catch kept deliberately tight to ensure that we _only_ catch exceptions due to\n      // this reflective access.\n      QueryPlanner.Factory factory;\n      try {\n        // See https://github.com/typetools/jdk/pull/235#pullrequestreview-3400922783\n        @SuppressWarnings(\"nullness\")\n        Object queryPlannerFactoryObj =\n            checkStateNotNull(\n                queryPlannerClass.getField(\"FACTORY\").get(null),\n                \"Static field %s.FACTORY is null. It must be a QueryPlanner.Factory instance.\",\n                queryPlannerClass);\n        factory = (QueryPlanner.Factory) queryPlannerFactoryObj;\n      } catch (NoSuchFieldException | IllegalAccessException exc) {\n        throw new RuntimeException(\n            String.format(","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/BeamSqlEnv.java#L316-L352","documentation":"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.","triggerScenarios":"Setting a custom queryPlannerClassName on BeamSqlEnvBuilder (or JDBC config) whose class is absent from the runtime classpath, then initializing the planner.","commonSituations":"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.","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"],"exampleFix":"// before\nbuilder.setQueryPlannerClassName(\"org.apache.beam.sql.MyPlanner\"); // not on classpath\n// after\nbuilder.setQueryPlannerClassName(\"org.apache.beam.sdk.extensions.sql.impl.planner BeamQueryPlanner\");\n// (use the exact FQCN: org.apache.beam.sdk.extensions.sql.impl.BeamQueryPlanner)","handlingStrategy":"try-catch","validationCode":"try { Class.forName(queryPlannerClassName); } catch (ClassNotFoundException e) { /* fail fast with clear message */ }","typeGuard":"boolean plannerClassPresent(String cn) { try { Class.forName(cn); return true; } catch (ClassNotFoundException e) { return false; } }","tryCatchPattern":"try { env = builder.build(); } catch (RuntimeException e) { if (e.getMessage().contains(\"Cannot find requested QueryPlanner\")) { /* fix classpath/config */ } throw e; }","preventionTips":["Verify planner artifact is a runtime dependency","Use exact fully-qualified class names","Prefer the default planner unless customization is needed"],"tags":["sql","reflection","classpath"],"backgroundTag":"class-not-found","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}