{"record":{"id":"9b9084e045e5d3ec","repo":"spring-projects/spring-security","slug":"required-class-classname-not-found","errorCode":null,"errorMessage":"Required class<className> not found","messagePattern":"Required class<className> not found","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"web/src/main/java/org/springframework/security/web/authentication/preauth/websphere/DefaultWASUsernameAndGroupsExtractor.java","lineNumber":179,"sourceCode":"\t\t\t\t\t+ Arrays.asList(args) + \")\";\n\t\t\tlogger.error(message, ex);\n\t\t\tthrow new RuntimeException(message, ex);\n\t\t}\n\t}\n\n\tprivate static Method getMethod(String className, String methodName, String[] parameterTypeNames) {\n\t\ttry {\n\t\t\tClass<?> c = Class.forName(className);\n\t\t\tint len = parameterTypeNames.length;\n\t\t\tClass<?>[] parameterTypes = new Class[len];\n\t\t\tfor (int i = 0; i < len; i++) {\n\t\t\t\tparameterTypes[i] = Class.forName(parameterTypeNames[i]);\n\t\t\t}\n\t\t\treturn c.getDeclaredMethod(methodName, parameterTypes);\n\t\t}\n\t\tcatch (ClassNotFoundException ex) {\n\t\t\tlogger.error(\"Required class\" + className + \" not found\");\n\t\t\tthrow new RuntimeException(\"Required class\" + className + \" not found\", ex);\n\t\t}\n\t\tcatch (NoSuchMethodException ex) {\n\t\t\tlogger.error(\"Required method \" + methodName + \" with parameter types (\" + Arrays.asList(parameterTypeNames)\n\t\t\t\t\t+ \") not found on class \" + className);\n\t\t\tthrow new RuntimeException(\"Required class\" + className + \" not found\", ex);\n\t\t}\n\t}\n\n\tprivate static Method getRunAsSubjectMethod() {\n\t\tif (getRunAsSubject == null) {\n\t\t\tgetRunAsSubject = getMethod(\"com.ibm.websphere.security.auth.WSSubject\", \"getRunAsSubject\",\n\t\t\t\t\tnew String[] {});\n\t\t}\n\t\treturn getRunAsSubject;\n\t}\n\n\tprivate static Method getGroupsForUserMethod() {\n\t\tif (getGroupsForUser == null) {","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/web/src/main/java/org/springframework/security/web/authentication/preauth/websphere/DefaultWASUsernameAndGroupsExtractor.java#L161-L197","documentation":"getMethod resolves a declared method on a WebSphere internal class by loading the class and its parameter types via Class.forName and calling getDeclaredMethod. When a required class (the target class or one of the parameter type names) cannot be found on the classpath, a ClassNotFoundException is caught and rethrown as a RuntimeException with the message \"Required class<className> not found\". This guards against calling WAS APIs that simply do not exist in the current environment.","triggerScenarios":"Calling any of getRunAsSubjectMethod, getGroupsForUserMethod, getSecurityNameMethod, or getNarrowMethod when the referenced WAS class (e.g. com.ibm.websphere.security.auth.WSSubject) or one of its parameter type names is not present on the classpath.","commonSituations":"Deploying the WebSphere pre-auth module on a non-WebSphere server (Tomcat, Jetty) where com.ibm.* classes are absent; missing was_publib / WAS runtime jars on the classpath; a WAS version rename or removal of an internal class; fat-jar packaging that excluded provider jars.","solutions":["Ensure the application runs on WebSphere/WAS and add the WAS runtime libraries (e.g. com.ibm.ws.runtime.jar, WAS_HOME/plugins) to the classpath.","Check the className in the message against your WAS version's javadoc - the internal class may have moved or been renamed in your WAS release.","If intentionally running outside WAS, switch to a different authentication mechanism instead of the WebSphere pre-auth module.","Use pf (class path) tooling or Class.forName in a test to confirm each com.ibm.websphere.security class resolves before startup.","Wrap extractor initialization in a startup check so missing WAS classes fail fast with a clear deployment error."],"exampleFix":"// before\n// runtime failure inside getMethod when com.ibm.* classes are missing\n// after\ntry {\n    Class.forName(\"com.ibm.websphere.security.auth.WSSubject\");\n} catch (ClassNotFoundException e) {\n    throw new IllegalStateException(\n        \"WebSphere runtime classes not on classpath - WASPreAuthenticatedProcessingHandler requires WebSphere/WAS\", e);\n}","handlingStrategy":"validation","validationCode":"public static void assertWasClassesPresent() {\n    String[] required = {\n        \"com.ibm.websphere.security.auth.WSSubject\",\n        \"com.ibm.websphere.security.cred.WSCredential\"\n    };\n    for (String name : required) {\n        try {\n            Class.forName(name);\n        } catch (ClassNotFoundException e) {\n            throw new IllegalStateException(\"Missing required WAS class: \" + name, e);\n        }\n    }\n}\n// call at startup before enabling the WAS pre-auth filter","typeGuard":"boolean wasClassPresent(String className) {\n    try {\n        Class.forName(className);\n        return true;\n    } catch (ClassNotFoundException e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    extractor.getWebSphereGroups(securityName);\n} catch (RuntimeException ex) {\n    if (ex.getCause() instanceof ClassNotFoundException) {\n        throw new IllegalStateException(\"WAS runtime classes missing from classpath\", ex);\n    }\n    throw ex;\n}","preventionTips":["Only deploy the websphere pre-auth package on WebSphere/WAS servers","Include WAS runtime jars (WAS_HOME/plugins, com.ibm.ws.runtime.jar) on the classpath","Add a startup classpath check for com.ibm.websphere.security classes","Document required WAS version to avoid internal API drift"],"tags":["reflection","websphere","classpath","classnotfound"],"backgroundTag":"class-not-found","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}