pentaho/pentaho-kettle · error · AuthenticationFactoryException

DefaultAuthenticationConsumerFactory.Constructor

Error message

DefaultAuthenticationConsumerFactory.Constructor

What it means

DefaultAuthenticationConsumerFactory wraps a consumer class and requires it to expose exactly one public constructor; otherwise it throws AuthenticationFactoryException with message key 'DefaultAuthenticationConsumerFactory.Constructor'. The factory cannot unambiguously pick how to construct the consumer.

Solutions

  1. Give the consumer class exactly one public constructor (the one taking the single provider/create argument).
  2. Reduce overloaded constructors or make extras private/package-private.
  3. Pass a different consumer class that satisfies the single-public-constructor contract.

Example fix

// before
public MyConsumer() {}
public MyConsumer(Provider p) {} // two public constructors
// after
public MyConsumer(Provider p) {}
private MyConsumer() {}
Defensive patterns

Strategy: validation

Validate before calling

if (MyConsumer.class.getConstructors().length != 1) {
  throw new IllegalStateException("Consumer must expose exactly one public constructor");
}

Try / catch

try { new DefaultAuthenticationConsumerFactory(MyConsumer.class); } catch (AuthenticationFactoryException e) { logError("Constructor contract violated", e); }

Prevention

When it happens

Trigger: new DefaultAuthenticationConsumerFactory(SomeConsumer.class) where consumerClass.getConstructors().length != 1 — the class has zero public constructors or more than one.

Common situations: Consumers with convenience/overloaded constructors; default-visibility constructor only (getConstructors() sees none); added a second constructor during refactoring.

Understand the failure class

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/core/auth/core/impl/DefaultAuthenticationConsumerFactory.java:36

import java.lang.reflect.Method;

import org.pentaho.di.core.auth.core.AuthenticationConsumer;
import org.pentaho.di.core.auth.core.AuthenticationConsumerFactory;
import org.pentaho.di.core.auth.core.AuthenticationFactoryException;
import org.pentaho.di.i18n.BaseMessages;

public class DefaultAuthenticationConsumerFactory implements AuthenticationConsumerFactory<Object, Object, Object> {
  private static final Class<?> PKG = DefaultAuthenticationConsumerFactory.class;
  private final Constructor<?> constructor;
  private final Class<Object> consumedType;
  private final Class<Object> returnType;
  private final Class<Object> createArgType;

  @SuppressWarnings( "unchecked" )
  public DefaultAuthenticationConsumerFactory( Class<?> consumerClass ) throws AuthenticationFactoryException {
    Constructor<?>[] constructors = consumerClass.getConstructors();
    if ( constructors.length != 1 ) {
      throw new AuthenticationFactoryException( BaseMessages.getString( PKG,
          "DefaultAuthenticationConsumerFactory.Constructor", getClass().getName(),
          consumerClass.getCanonicalName() ) );
    }

    constructor = constructors[0];
    Class<?>[] parameterTypes = constructor.getParameterTypes();
    if ( parameterTypes.length != 1 ) {
      throw new AuthenticationFactoryException( BaseMessages.getString( PKG,
          "DefaultAuthenticationConsumerFactory.Constructor.Arg", getClass().getName(), consumerClass
              .getCanonicalName() ) );
    }

    Method consumeMethod = null;
    Class<?> consumedType = Object.class;
    for ( Method method : consumerClass.getMethods() ) {
      if ( "consume".equals( method.getName() ) ) {
        Class<?>[] methodParameterTypes = method.getParameterTypes();
        if ( methodParameterTypes.length == 1 && consumedType.isAssignableFrom( methodParameterTypes[0] ) ) {

View on GitHub (pinned to f3058517a1)