pentaho/pentaho-kettle · error · KettleStepException

Error executing UserDefinedJavaClass.getFields():

Error message

Error executing UserDefinedJavaClass.getFields(): 

What it means

Thrown from UserDefinedJavaClassMeta.getFields() when reflection invocation of the cooked class's static getFields(boolean, RowMetaInterface, String, RowMetaInterface[], StepMeta, VariableSpace, List) method fails. The step's generated class was cooked but its getFields implementation threw an exception, which is wrapped in a KettleStepException.

Solutions

  1. Inspect the wrapped cause 'e' — the stack trace points at the failing line in your snippet's getFields logic.
  2. Guard against nulls in your getFields code (variables, environment, row meta may be unset at init time).
  3. Verify you don't modify output row structure based on runtime data not yet available at init.
  4. Test the transformation with a sample dataset; field calculation happens before rows flow.
  5. Avoid static state in your snippet that assumes processRow ran before getFields.

Example fix

// before
String v = getVariable("MY_VAR");
int n = Integer.parseInt(v);
// after
String v = getVariable("MY_VAR", "0");
int n;
try { n = Integer.parseInt(v); } catch (NumberFormatException e) { n = 0; }
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure variables referenced in snippets have defaults
if (getVariable("MY_VAR", null) == null) throw new IllegalStateException("MY_VAR not set");

Try / catch

try {
  trans.execute(null); // init path triggers getFields
} catch (KettleStepException e) {
  if (e.getMessage().contains("UserDefinedJavaClass.getFields()")) {
    e.getCause().printStackTrace(); // locate failing snippet line
  }
}

Prevention

When it happens

Trigger: During transformation init/field propagation, getFieldsMethod.invoke() throws because the user's code (or the generated class) raises an exception while computing output fields, or the method signature doesn't resolve.

Common situations: User code in the Class code tab throwing inside getFields (e.g. NPE on an unset variable); clearResultFields/field info lists containing nulls; version mismatch where generated getFields signature changed.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/userdefinedjavaclass/UserDefinedJavaClassMeta.java:489

    VariableSpace space, Repository repository, IMetaStore metaStore ) throws KettleStepException {
    if ( !checkClassCookings( getLog() ) ) {
      if ( cookErrors.size() > 0 ) {
        throw new KettleStepException( "Error initializing UserDefinedJavaClass to get fields: ", cookErrors
          .get( 0 ) );
      } else {
        return;
      }
    }

    try {
      Method getFieldsMethod =
        cookedTransformClass.getMethod(
          "getFields", boolean.class, RowMetaInterface.class, String.class, RowMetaInterface[].class,
          StepMeta.class, VariableSpace.class, List.class );
      getFieldsMethod.invoke(
        null, isClearingResultFields(), row, originStepname, info, nextStep, space, getFieldInfo() );
    } catch ( Exception e ) {
      throw new KettleStepException( "Error executing UserDefinedJavaClass.getFields(): ", e );
    }
  }

  public String getXML() {
    StringBuilder retval = new StringBuilder( 300 );

    retval.append( String.format( "\n    <%s>", ElementNames.definitions.name() ) );
    for ( UserDefinedJavaClassDef def : definitions ) {
      retval.append( String.format( "\n        <%s>", ElementNames.definition.name() ) );
      retval.append( "\n        " ).append(
        XMLHandler.addTagValue( ElementNames.class_type.name(), def.getClassType().name() ) );
      retval.append( "\n        " ).append(
        XMLHandler.addTagValue( ElementNames.class_name.name(), def.getClassName() ) );
      retval.append( "\n        " );
      retval.append( XMLHandler.addTagValue( ElementNames.class_source.name(), def.getSource() ) );
      retval.append( String.format( "\n        </%s>", ElementNames.definition.name() ) );
    }
    retval.append( String.format( "\n    </%s>", ElementNames.definitions.name() ) );

View on GitHub (pinned to f3058517a1)