pentaho/pentaho-kettle · error · KettleDatabaseException

Exception while loading class

Error message

Exception while loading class

What it means

loadStaticDriver's final catch (Exception) wraps any unexpected error during driver class loading/registration (other than ClassNotFoundException/NoClassDefFoundError) into KettleDatabaseException("Exception while loading class"). Typically this is a linkage or initialization error inside the driver class's static initializer.

Solutions

  1. Inspect the wrapped cause — ExceptionInInitializerError exposes the static-init failure via getCause()
  2. Replace the driver jar with a fresh, compatible download
  3. Resolve conflicting dependency versions on the classpath
  4. Run with -verbose:class to confirm the class is loaded from the expected jar location

Example fix

// before
// conflicting protobuf jars on classpath -> static init fails
lib/protobuf-java-2.5.0.jar
lib/protobuf-java-3.19.0.jar

// after
lib/protobuf-java-3.19.0.jar  // single version matching driver requirement
Defensive patterns

Strategy: try-catch

Validate before calling

try {
  Class.forName( driverClassname, true, loader );
} catch ( Throwable t ) {
  log.error( "Driver failed static initialization: " + t.getCause(), t );
}

Try / catch

try {
  db.connect();
} catch ( KettleDatabaseException e ) {
  if ( "Exception while loading class".equals( e.getMessage() ) ) {
    Throwable initFailure = e.getCause() != null ? e.getCause().getCause() : null;
    log.error( "Driver init problem: " + initFailure, initFailure );
  }
}

Prevention

When it happens

Trigger: ExceptionInInitializerError-like conditions or other RuntimeExceptions thrown when Class.forName triggers the driver's static registration block — corrupted jars, incompatible dependency versions, or static init that depends on missing system properties.

Common situations: Driver jar built for a different JVM/dependency version, partially downloaded/corrupted jar, conflicting versions of a shared dependency (e.g. protobuf vs newer drivers), security policy blocking class definition.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/database/Database.java:657

  private void loadStaticDriver( String classname, PluginInterface plugin ) throws KettleDatabaseException {
    try {
      synchronized ( java.sql.DriverManager.class ) {
        ClassLoader classLoader = PluginRegistry.getInstance().getClassLoader( plugin );
        Class<?> driverClass = classLoader.loadClass( classname );
        // Only need DelegatingDriver for drivers not from our classloader
        if ( driverClass.getClassLoader() != this.getClass().getClassLoader() ) {
          registerDelegatingDriver( driverClass );
        } else {
          // Trigger static register block in driver class
          Class.forName( classname );
        }
      }
    } catch ( NoClassDefFoundError | ClassNotFoundException e ) {
      throw new KettleDatabaseException( BaseMessages.getString( PKG,
        "Database.Exception.UnableToFindClassMissingDriver", classname, plugin.getName() ), e );
    } catch ( Exception e ) {
      throw new KettleDatabaseException( "Exception while loading class", e );
    }
  }

  private void registerDelegatingDriver( Class<?> driverClass ) throws KettleDatabaseException {
    String pluginId =
      PluginRegistry.getInstance().getPluginId( DatabasePluginType.class, databaseMeta.getDatabaseInterface() );
    Set<String> registeredDriversFromPlugin = registeredDrivers.computeIfAbsent( pluginId, k -> new HashSet<>() );
    // Prevent registering multiple delegating drivers for same class, plugin
    if ( !registeredDriversFromPlugin.contains( driverClass.getCanonicalName() ) ) {
      try {
        DriverManager.registerDriver( new DelegatingDriver( (Driver) driverClass.getDeclaredConstructor().newInstance() ) );
      } catch ( InstantiationException | IllegalAccessException | NoSuchMethodException | java.lang.reflect.InvocationTargetException | SQLException e ) {
        throw new KettleDatabaseException(
          "Unable to register delegating driver for class " + driverClass.getCanonicalName(), e );
      }
      registeredDriversFromPlugin.add( driverClass.getCanonicalName() );
    }
  }

View on GitHub (pinned to f3058517a1)