{"record":{"id":"d880e461c967a9dd","repo":"pentaho/pentaho-kettle","slug":"jdbcdriverresolver-driverid-must-not-be-null-or-blank","errorCode":null,"errorMessage":"JdbcDriverResolver: driverId must not be null or blank","messagePattern":"JdbcDriverResolver: driverId must not be null or blank","errorType":"validation","errorClass":"KettleDatabaseException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/database/JdbcDriverResolver.java","lineNumber":97,"sourceCode":"   */\n  private static final ConcurrentHashMap<String, ReentrantLock> DOWNLOAD_LOCKS = new ConcurrentHashMap<>();\n\n  private JdbcDriverResolver() {\n    // utility class\n  }\n\n  /**\n   * Returns an absolute path to the JDBC driver JAR.\n   *\n   * <p>If {@code driverId} points to an existing file it is returned immediately.\n   * Otherwise the resolution chain described in the class Javadoc is followed.\n   *\n   * @return absolute path of the resolved JAR file\n   * @throws KettleDatabaseException if the JAR cannot be found or downloaded\n   */\n  public static String resolve( String driverId ) throws KettleDatabaseException {\n    if ( driverId == null || driverId.trim().isEmpty() ) {\n      throw new KettleDatabaseException( \"JdbcDriverResolver: driverId must not be null or blank\" );\n    }\n    String configuredPath = driverId + \".jar\";\n    // 1 — configured path exists as-is\n    if ( existsAsFile( configuredPath ) ) {\n      return configuredPath;\n    }\n\n    String jarName = Paths.get( configuredPath ).getFileName().toString();\n    log.logBasic( \"JdbcDriverResolver: JAR not found at configured path '\" + configuredPath\n      + \"' — searching by file name '\" + jarName + \"'\" );\n\n    // 2 — JDBC_DRIVERS_DIRECTORY: env var wins over system property (via Const)\n    String resolved = tryDirectory( Const.getJdbcDriversDirectory(), jarName, \"Const.getJdbcDriversDirectory()\" );\n    if ( resolved != null ) {\n      return resolved;\n    }\n\n    // 3 — JDBC_DRIVERS_DIRECTORY from kettle.properties (on-prem / BA Server)","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/database/JdbcDriverResolver.java#L79-L115","documentation":"JdbcDriverResolver.resolve(driverId) requires a non-null, non-blank driver identifier because it is used to build the JAR file name (driverId + \".jar\") and the download URL. It performs a fail-fast guard at the top of the method, throwing KettleDatabaseException when the argument is null, empty, or whitespace.","triggerScenarios":"Calling JdbcDriverResolver.resolve(null) or resolve(\"\") or resolve(\"   \") — typically when the database type has no mapped driverId, or the caller passes an uninitialized field from configuration.","commonSituations":"DatabaseMeta with an unset/blank driver class; a scripting step building the driverId dynamically from user input; resolveAll() given a list containing blank entries (though resolveAll skips those).","solutions":["Ensure the caller supplies a valid driverId before calling resolve","Default the driverId from the DatabaseMeta (e.g. connection's getDriverClass()) when missing","Trim user-supplied input and reject blank values upstream with a clearer UI error"],"exampleFix":"// before\nString path = JdbcDriverResolver.resolve( driverId ); // NPE-adjacent blank input\n// after\nif ( driverId == null || driverId.trim().isEmpty() ) {\n  throw new IllegalArgumentException( \"driverId is required (e.g. postgresql)\" );\n}\nString path = JdbcDriverResolver.resolve( driverId.trim() );","handlingStrategy":"validation","validationCode":"if ( driverId == null || driverId.trim().isEmpty() ) {\n  throw new IllegalArgumentException( \"driverId is required before resolving a driver JAR\" );\n}","typeGuard":"boolean isValidDriverId( String s ) { return s != null && !s.trim().isEmpty(); }","tryCatchPattern":"try { path = JdbcDriverResolver.resolve( driverId ); } catch ( KettleDatabaseException e ) { failFast( \"blank/invalid driverId: \" + driverId ); }","preventionTips":["Initialize driverId from DatabaseMeta.getDriverClass() or plugin defaults","Trim all user input before resolving","Validate connection configuration before starting jobs"],"tags":["argument-validation","jdbc","driver"],"backgroundTag":"empty-required-field","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}