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
- Ensure the file at jarAbsolutePath is a real .jar file (rename or re-download it)
- Pass only the driverId (without extension) — resolve() appends '.jar' itself
- 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
- Pass bare driverIds, not pre-built paths
- Keep only .jar artifacts in the drivers directory
- Never rename driver artifacts to other extensions
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
- Dynamic driver path does not point to a JAR file
- A connection of type PALO is expected
- A connection of type PALO is expected
- A server socket allocation always has to accompanied by a…
- A server socket allocation always has to accompanied by…
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)