pentaho/pentaho-kettle · error · KettleDatabaseException

JdbcDriverResolver: not a JAR file: " + jarAbsolutePath

Error message

JdbcDriverResolver: not a JAR file: " + jarAbsolutePath

What it means

toJarUrl() additionally validates that the file name ends with .jar (case-insensitive). A path that exists but is not a JAR (e.g. a directory-named path, a .zip, or a class file) is rejected with this KettleDatabaseException.

Solutions

  1. Ensure the file at jarAbsolutePath is a real .jar file (rename or re-download it)
  2. Pass only the driverId (without extension) — resolve() appends '.jar' itself
  3. Inspect what file exists at the path in the message; remove or replace non-jar artifacts

Example fix

// before
String path = JdbcDriverResolver.resolve( "/opt/drivers/postgresql-42.jar" ); // yields .jar.jar naming issues
// after
String path = JdbcDriverResolver.resolve( "postgresql-42" );
Defensive patterns

Strategy: validation

Validate before calling

File f = new File( path );
if ( !f.getName().toLowerCase().endsWith( ".jar" ) ) throw new IllegalArgumentException( "not a .jar: " + path );

Type guard

boolean isJarFile( String p ) { return new File( p ).getName().toLowerCase().endsWith( ".jar" ); }

Try / catch

try { toJarUrl( path ); } catch ( KettleDatabaseException e ) { if ( e.getMessage().contains( "not a JAR file" ) ) fixExtensionOrReplace( path ); throw e; }

Prevention

When it happens

Trigger: Passing a driverId containing a path/extension such that the resolved file is not a *.jar — e.g. driverId 'mylib' resolving a file 'mylib' (no extension), or a path pointing to a directory-like regular file or a .zip driver.

Common situations: Users configuring a full JAR path already containing '.jar' so the resolver builds 'foo.jar.jar'-style or non-jar artifacts; pointing the drivers directory at files with .zip extension; misconfigured driverId from database types.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/6a8ffb655e799e00. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/database/JdbcDriverResolver.java:402

    return Files.isRegularFile( Paths.get( path ) );
  }

  /**
   * Converts an absolute JAR path to a {@link URL}, validating that the file exists
   * and has a {@code .jar} extension.
   *
   * @param jarAbsolutePath absolute path to the JAR file
   * @return the file URL
   * @throws KettleDatabaseException if the file does not exist, is not a regular file,
   *                                  does not end with .jar, or cannot be converted
   */
  private static URL toJarUrl( String jarAbsolutePath ) throws KettleDatabaseException {
    File jarFile = new File( jarAbsolutePath );
    if ( !jarFile.exists() || !jarFile.isFile() ) {
      throw new KettleDatabaseException( "JdbcDriverResolver: JAR not found: " + jarAbsolutePath );
    }
    if ( !jarFile.getName().toLowerCase().endsWith( ".jar" ) ) {
      throw new KettleDatabaseException( "JdbcDriverResolver: not a JAR file: " + jarAbsolutePath );
    }
    try {
      return jarFile.toPath().toUri().toURL();
    } catch ( Exception e ) {
      throw new KettleDatabaseException( "JdbcDriverResolver: Cannot convert path to URL: " + jarAbsolutePath, e );
    }
  }
}

View on GitHub (pinned to f3058517a1)