{"record":{"id":"66adec04f163689b","repo":"pentaho/pentaho-kettle","slug":"pluginregistry003","errorCode":"PLUGINREGISTRY003","errorMessage":"Class not found","messagePattern":"Class not found","errorType":"error_code","errorClass":"KettlePluginException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/plugins/PluginRegistry.java","lineNumber":523,"sourceCode":"        throw new KettlePluginClassMapException( BaseMessages.getString( PKG,\n            \"PluginRegistry.RuntimeError.NoValidClassRequested.PLUGINREGISTRY002\", plugin.getName(),\n            pluginClass.getName() ) );\n      }\n\n      try {\n        Class<? extends T> cl;\n        if ( plugin.isNativePlugin() ) {\n          cl = (Class<? extends T>) Class.forName( className );\n        } else {\n          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   *","sourceCodeStart":505,"sourceCodeEnd":541,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/plugins/PluginRegistry.java#L505-L541","documentation":"At the end of loadClass, the registry loads the class via the plugin's URLClassLoader (ucl.loadClass(className)) and instantiates it. A ClassNotFoundException is rethrown as KettlePluginException 'Class not found' (PLUGINREGISTRY003) with the original as cause — the plugin jar/folder does not contain the mapped class name.","triggerScenarios":"ucl.loadClass(className) fails because the class named in the plugin's metadata (mainClassFolder/classMap entry) is absent from the plugin's jar/folder URLs — wrong class name, missing jar entry, or the jar wasn't added to the classloader.","commonSituations":"Package/refactor renamed the class but plugin.xml or annotation still lists the old FQN; incomplete plugin deployment (jar missing some classes); dependency classes referenced by the plugin are absent so a NoClassDefFoundError surfaces as lookup failure; class in a nested jar VFS can't open.","solutions":["Check the class name in the plugin annotation/plugin.xml against the actual FQN in the jar (javap or jar tf | grep <ClassName>).","Run jar tf plugin.jar to confirm the class file exists at the expected path.","Redeploy a complete plugin build; if dependencies are missing, add them to the plugin's lib folder.","Verify the plugin folder's jars are the version matching the metadata (no stale duplicate jars)."],"exampleFix":"// before\n@Step(id = \"MyStep\", classnamelist = {\"com.acme.step.MyStepMeta\"}) // actual: com.acme.step.MyStepMetaNew\n\n// after\n@Step(id = \"MyStep\", classnamelist = {\"com.acme.step.MyStepMetaNew\"})","handlingStrategy":"validation","validationCode":"String fqn = \"com.acme.MyStepMeta\";\ntry {\n  Class.forName(fqn, false, pluginClassLoader);\n} catch (ClassNotFoundException e) {\n  throw new IllegalStateException(\"Class not in plugin jar: \" + fqn);\n}","typeGuard":null,"tryCatchPattern":"try {\n  Object o = PluginRegistry.getInstance().loadClass(plugin, pluginClass);\n} catch (KettlePluginException e) {\n  if (e.getMessage().contains(\"Class not found\")) {\n    log.error(\"Mapped class missing from \" + plugin.getName() + \" jar; verify plugin.xml/annotation FQNs\", e);\n  }\n  throw e;\n}","preventionTips":["Run 'jar tf plugin.jar | grep ClassName' before deploying to verify mapped classes exist.","Add a build-time check that every class in plugin.xml/annotations exists in the artifact.","Avoid renaming plugin classes without updating metadata in the same commit.","Place plugin dependencies in the plugin's own lib folder so the URLClassLoader sees them."],"tags":["kettle","plugins","classnotfound","classloading"],"backgroundTag":"class-not-found","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"}