{"record":{"id":"4311e86be1f62121","repo":"pentaho/pentaho-kettle","slug":"scriptmeta-exception-unabletoparsexmlforadditionalclasses","errorCode":null,"errorMessage":"ScriptMeta.Exception.UnableToParseXMLforAdditionalClasses","messagePattern":"ScriptMeta\\.Exception\\.UnableToParseXMLforAdditionalClasses","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/script/ScriptMeta.java","lineNumber":826,"sourceCode":"      Document dom = XMLHandler.loadXMLFile( DefaultBowl.getInstance(),\n                                             strActPath + \"/plugins/steps/ScriptValues_mod/plugin.xml\" );\n      Node stepnode = dom.getDocumentElement();\n      Node libraries = XMLHandler.getSubNode( stepnode, \"js_libraries\" );\n      int nbOfLibs = XMLHandler.countNodes( libraries, \"js_lib\" );\n      additionalClasses = new ScriptAddClasses[nbOfLibs];\n      for ( int i = 0; i < nbOfLibs; i++ ) {\n        Node fnode = XMLHandler.getSubNodeByNr( libraries, \"js_lib\", i );\n        String strJarName = XMLHandler.getTagAttribute( fnode, \"name\" );\n        String strClassName = XMLHandler.getTagAttribute( fnode, \"classname\" );\n        String strJSName = XMLHandler.getTagAttribute( fnode, \"js_name\" );\n\n        Class<?> addClass =\n          LoadAdditionalClass( strActPath + \"/plugins/steps/ScriptValues_mod/\" + strJarName, strClassName );\n        Object addObject = addClass.newInstance();\n        additionalClasses[i] = new ScriptAddClasses( addClass, addObject, strJSName );\n      }\n    } catch ( Exception e ) {\n      throw new KettleException( BaseMessages.getString(\n        PKG, \"ScriptMeta.Exception.UnableToParseXMLforAdditionalClasses\" ), e );\n    }\n  }\n\n  private static Class<?> LoadAdditionalClass( String strJar, String strClassName ) throws KettleException {\n    try {\n      Thread t = Thread.currentThread();\n      ClassLoader cl = t.getContextClassLoader();\n      URL u = new URL( \"jar:file:\" + strJar + \"!/\" );\n      // We never know what else the script wants to load with the class loader, so lets not close it just like that.\n      @SuppressWarnings( \"resource\" )\n      KettleURLClassLoader kl = new KettleURLClassLoader( new URL[] { u }, cl );\n      Class<?> toRun = kl.loadClass( strClassName );\n      return toRun;\n    } catch ( Exception e ) {\n      throw new KettleException(\n        BaseMessages.getString( PKG, \"ScriptMeta.Exception.UnableToLoadAdditionalClass\" ), e );\n    }","sourceCodeStart":808,"sourceCodeEnd":844,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/script/ScriptMeta.java#L808-L844","documentation":"This ScriptMeta constructor parses 'additional classes' (Java classes shipped with jars to be exposed to the JavaScript step) from XML, then loads each jar/class via LoadAdditionalClass from the plugin path. Any failure reading the XML or instantiating the class is wrapped in KettleException 'UnableToParseXMLforAdditionalClasses'.","triggerScenarios":"Loading a transformation whose Script step declares additional class entries, when strJarName/strClassName XML tags are malformed, the plugin path 'plugins/steps/ScriptValues_mod/' + jar is missing, or addClass.newInstance() fails.","commonSituations":"Transformation moved between machines where the extra jar isn't installed in the plugin directory; jar compiled for a different Java version; typo in class name in the step XML.","solutions":["Verify the jar named in the step XML exists under plugins/steps/ScriptValues_mod/ on this machine.","Check the class name spelling and that the jar actually contains it (jar tf).","Ensure the JVM version can load the class (compile target compatible with runtime JDK).","Inspect the nested cause to distinguish XML parsing vs class loading vs instantiation failure."],"exampleFix":"// before: step references missing jar in XML\n<strJarName>MyHelper.jar</strJarName> // jar absent on this node\n// after: deploy the jar\ncp MyHelper.jar $PENTHO/plugins/steps/ScriptValues_mod/","handlingStrategy":"validation","validationCode":"// Verify jar and plugin dir before loading the transformation\nFile jar = new File(\"plugins/steps/ScriptValues_mod/MyHelper.jar\");\nif (!jar.isFile()) throw new IllegalStateException(\"missing jar: \" + jar);","typeGuard":null,"tryCatchPattern":"try { loadTransformation(); } catch (KettleException e) {\n  if (e.getMessage().contains(\"UnableToParseXMLforAdditionalClasses\")) {\n    // inspect cause: XML parse vs jar missing vs newInstance\n  }\n}","preventionTips":["Deploy all referenced plugin jars to every node","Use fully qualified class names in step XML","Keep JVM version compatible with jar targets","Diff step XML against a known-good transformation"],"tags":["pdi","xml","classloading","plugin"],"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"}