{"record":{"id":"e048f59f80c2742e","repo":"MyCATApache/Mycat-Server","slug":"cannot-find-class-classname","errorCode":null,"errorMessage":"Cannot find class ${className}","messagePattern":"Cannot find class (.+?)","errorType":"exception","errorClass":"ObjectAccessException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/config/util/ReflectionProvider.java","lineNumber":169,"sourceCode":"                stream.writeShort(ObjectStreamConstants.STREAM_VERSION);\n                stream.writeByte(ObjectStreamConstants.TC_OBJECT);\n                stream.writeByte(ObjectStreamConstants.TC_CLASSDESC);\n                stream.writeUTF(type.getName());\n                stream.writeLong(ObjectStreamClass.lookup(type).getSerialVersionUID());\n                stream.writeByte(2); // classDescFlags (2 = Serializable)\n                stream.writeShort(0); // field count\n                stream.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA);\n                stream.writeByte(ObjectStreamConstants.TC_NULL);\n                data = bytes.toByteArray();\n                serializedDataCache.put(type, data);\n            }\n\n            ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(data));\n            return in.readObject();\n        } catch (IOException e) {\n            throw new ObjectAccessException(\"Cannot create \" + type.getName() + \" by JDK serialization\", e);\n        } catch (ClassNotFoundException e) {\n            throw new ObjectAccessException(\"Cannot find class \" + e.getMessage());\n        }\n    }\n\n    private boolean fieldModifiersSupported(Field field) {\n        return !(Modifier.isStatic(field.getModifiers()) || Modifier.isTransient(field.getModifiers()));\n    }\n\n    private void validateFieldAccess(Field field) {\n        if (Modifier.isFinal(field.getModifiers())) {\n            if (JVMInfo.is15()) {\n                field.setAccessible(true);\n            } else {\n                throw new ObjectAccessException(\"Invalid final field \" + field.getDeclaringClass().getName() + \".\"\n                        + field.getName());\n            }\n        }\n    }\n","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/config/util/ReflectionProvider.java#L151-L187","documentation":"During JDK-serialization-based instantiation, ObjectInputStream.readObject throws ClassNotFoundException when a class referenced in the serialized stream cannot be loaded by the current classloader. The provider converts it into ObjectAccessException 'Cannot find class <name>', where <name> comes from e.getMessage().","triggerScenarios":"readObject encounters a class in the byte stream that is not on the classpath or is not loadable by the thread/context classloader (e.g. class renamed/moved between versions, different classloader in app-server).","commonSituations":"Upgrading mycat or a dependency so a serialized class's package/name changed; deploying in a servlet container where the webapp classloader cannot see the class; typo'd or removed class referenced in cached serialized data.","solutions":["Add the missing class (name in the message) back to the classpath or restore its original package name","Ensure the thread context classloader used by ObjectInputStream can load the class (Thread.currentThread().setContextClassLoader(...))","Invalidate the serializedDataCache so fresh bytes are generated from loadable classes","Check for serialVersionUID/name mismatches after dependency upgrades"],"exampleFix":"// before\nObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(data)); // data references moved class\n// after\nThread.currentThread().setContextClassLoader(MyClass.class.getClassLoader());\nObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(data));","handlingStrategy":"try-catch","validationCode":"// verify all classes referenced by cached serialized bytes are loadable\nThread.currentThread().setContextClassLoader(type.getClassLoader());\nClass.forName(expectedClassName, true, type.getClassLoader());","typeGuard":null,"tryCatchPattern":"try {\n    Object o = provider.newInstance(type);\n} catch (ObjectAccessException e) {\n    if (e.getMessage().startsWith(\"Cannot find class\")) {\n        Thread.currentThread().setContextClassLoader(type.getClassLoader());\n        Object o2 = provider.newInstance(type);\n    }\n}","preventionTips":["Keep the thread context classloader aligned with the app classloader","Avoid renaming/moving serialized classes between releases","Purge serialized caches on dependency upgrades","Pin serialVersionUIDs to reduce stream/class drift"],"tags":["class-not-found","serialization","classloader"],"backgroundTag":"class-not-found","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}