pentaho/pentaho-kettle · error · KettlePluginException
PLUGINREGISTRY004
PLUGINREGISTRY004
Error message
Unable to instantiate class
What it means
In loadClass, after the class is loaded, cl.newInstance() instantiates it. An InstantiationException is rethrown as KettlePluginException 'Unable to instantiate class' (PLUGINREGISTRY004). Java throws InstantiationException when the class is abstract, an interface, or has no accessible no-arg constructor.
Solutions
- Point the plugin metadata (annotation/plugin.xml) at the concrete class, not an interface or abstract class.
- Add a public no-argument constructor to the plugin class.
- Make the class public and non-abstract.
- If the class needs parameters, implement the expected plugin pattern (Kettle instantiates via no-arg constructor then calls init/setDefaults).
Example fix
// before
public class MyStepMeta extends BaseStepMeta {
public MyStepMeta(String config) { ... } // no no-arg ctor
}
// after
public class MyStepMeta extends BaseStepMeta {
public MyStepMeta() { }
public MyStepMeta(String config) { this(); ... }
} Defensive patterns
Strategy: validation
Validate before calling
Class<?> cl = pluginClassLoader.loadClass(fqn);
int mods = cl.getModifiers();
if (Modifier.isAbstract(mods) || Modifier.isInterface(mods) || !Modifier.isPublic(mods)) {
throw new IllegalStateException("Cannot instantiate: " + fqn);
}
cl.getDeclaredConstructor(); // throws if no no-arg ctor Type guard
static boolean isInstantiable(Class<?> c) {
int m = c.getModifiers();
try {
c.getDeclaredConstructor();
} catch (NoSuchMethodException e) { return false; }
return Modifier.isPublic(m) && !Modifier.isAbstract(m) && !c.isInterface();
} Try / catch
try {
return PluginRegistry.getInstance().loadClass(plugin, pluginClass);
} catch (KettlePluginException e) {
if (e.getMessage().contains("Unable to instantiate")) {
log.error("Check that " + plugin + " maps a concrete public class with a no-arg constructor", e);
}
throw e;
} Prevention
- Map concrete implementation classes, never interfaces or abstract bases.
- Always provide a public no-arg constructor on plugin classes.
- Write a test that instantiates every mapped plugin class reflectively.
- Follow the Kettle plugin lifecycle pattern instead of custom constructors.
When it happens
Trigger: cl.newInstance() on the resolved plugin class throws InstantiationException — the mapped class is abstract or an interface, or lacks a public no-argument constructor, so the registry cannot create an instance.
Common situations: A plugin metadata entry points at the interface or abstract base class instead of the concrete implementation; the plugin class defines only parameterized constructors; Kotlin/other-language class compiled without a no-arg constructor; class is not public.
Related errors
- PLUGINREGISTRY005
- Unable to instantiate object for
- Unable to instantiate object for
- Error executing UserDefinedJavaClass.getFields():
- KettleMissingPluginsException( getErrorMessage(…
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/39c6f42f6eff6349.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/plugins/PluginRegistry.java:526
}
try {
Class<? extends T> cl;
if ( plugin.isNativePlugin() ) {
cl = (Class<? extends T>) Class.forName( className );
} else {
ClassLoader ucl = getClassLoader( plugin );
// Load the class.
cl = (Class<? extends T>) ucl.loadClass( className );
}
return cl.newInstance();
} catch ( ClassNotFoundException e ) {
throw new KettlePluginException( BaseMessages.getString(
PKG, "PluginRegistry.RuntimeError.ClassNotFound.PLUGINREGISTRY003" ), e );
} catch ( InstantiationException e ) {
throw new KettlePluginException( BaseMessages.getString(
PKG, "PluginRegistry.RuntimeError.UnableToInstantiateClass.PLUGINREGISTRY004" ), e );
} catch ( IllegalAccessException e ) {
throw new KettlePluginException( BaseMessages.getString(
PKG, "PluginRegistry.RuntimeError.IllegalAccessToClass.PLUGINREGISTRY005" ), e );
} catch ( Throwable e ) {
e.printStackTrace();
throw new KettlePluginException( BaseMessages.getString(
PKG, "PluginRegistry.RuntimeError.UnExpectedErrorLoadingClass.PLUGINREGISTRY007" ), e );
}
}
}
/**
* Add a PluginType to be managed by the registry
*
* @param type
*/
public static void addPluginType( PluginTypeInterface type ) {View on GitHub (pinned to f3058517a1)