{"record":{"id":"b16d1f80c917517b","repo":"pentaho/pentaho-kettle","slug":"pluginregistry007","errorCode":"PLUGINREGISTRY007","errorMessage":"Unexpected error loading class:","messagePattern":"Unexpected error loading class:","errorType":"error_code","errorClass":"KettlePluginException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/plugins/PluginRegistry.java","lineNumber":533,"sourceCode":"          ClassLoader ucl = getClassLoader( plugin );\n\n          // Load the class.\n          cl = (Class<? extends T>) ucl.loadClass( className );\n        }\n\n        return cl.newInstance();\n      } catch ( ClassNotFoundException e ) {\n        throw new KettlePluginException( BaseMessages.getString(\n            PKG, \"PluginRegistry.RuntimeError.ClassNotFound.PLUGINREGISTRY003\" ), e );\n      } catch ( InstantiationException e ) {\n        throw new KettlePluginException( BaseMessages.getString(\n            PKG, \"PluginRegistry.RuntimeError.UnableToInstantiateClass.PLUGINREGISTRY004\" ), e );\n      } catch ( IllegalAccessException e ) {\n        throw new KettlePluginException( BaseMessages.getString(\n            PKG, \"PluginRegistry.RuntimeError.IllegalAccessToClass.PLUGINREGISTRY005\" ), e );\n      } catch ( Throwable e ) {\n        e.printStackTrace();\n        throw new KettlePluginException( BaseMessages.getString(\n            PKG, \"PluginRegistry.RuntimeError.UnExpectedErrorLoadingClass.PLUGINREGISTRY007\" ), e );\n      }\n    }\n  }\n\n  /**\n   * Add a PluginType to be managed by the registry\n   *\n   * @param type\n   */\n  public static void addPluginType( PluginTypeInterface type ) {\n    pluginTypes.add( type );\n  }\n\n  /**\n   * Added so we can tell when types have been added (but not necessarily registered)\n   *\n   * @return the list of added plugin types","sourceCodeStart":515,"sourceCodeEnd":551,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/plugins/PluginRegistry.java#L515-L551","documentation":"PLUGINREGISTRY007 is thrown by PluginRegistry.loadClass when any unexpected Throwable (not ClassNotFoundException, InstantiationException, or IllegalAccessException) escapes while instantiating a plugin class via Class.forName().newInstance(). It is a catch-all in Kettle's plugin registry: the plugin id resolved to a class, but constructing it blew up in an unforeseen way. The original Throwable is chained as the cause and printed to stderr before the KettlePluginException is thrown.","triggerScenarios":"Calling PluginRegistry.loadClass(PluginInterface, Class<T>) or loadClass(pluginId, className, Class<T>) where the target class's static initializer, no-arg constructor, or newInstance() path throws a RuntimeException/Error (e.g. ExceptionInInitializerError, NoSuchMethodError from mismatched jars, ClassFormatError from a corrupted jar), and the plugin's declared class instantiation path is exercised.","commonSituations":"A plugin jar is compiled against a different Kettle/metadata version than the runtime (NoSuchMethodError/NoClassDefFoundError surfacing as Throwable); a plugin class throws in a static initializer; a corrupted or partially deployed plugin jar; classpath conflicts where two plugin versions shadow each other.","solutions":["Inspect the chained 'cause' (the stack trace printed to stderr) to identify the real Throwable and fix the underlying class-loading or initialization problem.","Verify the plugin jar version matches the Kettle/PDI runtime version; redeploy a clean copy of the plugin directory.","Check for duplicate/conflicting copies of the plugin class on the classpath and remove stale jars from lib/ or the plugin folder.","If you own the plugin class, move risky work out of the static initializer and constructor so instantiation cannot throw.","If you are a caller, catch KettlePluginException and fall back to a default implementation or fail fast with a clear message."],"exampleFix":"// before: deployment mixes jar versions\nplugins/myplugin/myplugin-8.0.jar  vs. runtime PDI 9.x\n// after\nplugins/myplugin/myplugin-9.2.jar  (matching runtime version); inspect printStackTrace() output for the chained cause","handlingStrategy":"try-catch","validationCode":"String cls = plugin.getMainClass() != null ? plugin.getMainClass() : className;\nif (cls == null || cls.isEmpty()) throw new IllegalStateException(\"Plugin \" + plugin + \" has no class to load\");\ntry { Class.forName(cls, false, getClass().getClassLoader()); } catch (Throwable t) { /* resolve before loadClass */ }","typeGuard":"boolean isLoadable(String className) {\n  try { Class.forName(className, false, getClass().getClassLoader()); return true; }\n  catch (Throwable t) { return false; }\n}","tryCatchPattern":"try {\n  T instance = PluginRegistry.getInstance().loadClass(plugin, className, MyInterface.class);\n} catch (KettlePluginException e) {\n  LOG.error(\"Plugin class instantiation failed (PLUGINREGISTRY007)\", e); // inspect e.getCause()\n  throw new DeploymentException(\"Bad plugin jar/version: \" + plugin, e);\n}","preventionTips":["Keep plugin jar versions aligned with the PDI/Kettle runtime version.","Avoid throwing from plugin class static initializers and no-arg constructors.","After upgrading Kettle, redeploy plugin folders from clean builds.","Always log the chained cause of KettlePluginException, since 007 hides the real Throwable inside it."],"tags":["plugin-loading","class-not-found","reflection","kettle"],"backgroundTag":"module-init-failed","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}