{"record":{"id":"a19e48c11547d169","repo":"frohoff/ysoserial","slug":"couldn-t-find-file","errorCode":null,"errorMessage":"couldn't find '${file}'","messagePattern":"couldn't find '(.+?)'","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/main/java/ysoserial/payloads/util/ClassFiles.java","lineNumber":31,"sourceCode":"\t\tString str;\n\t\tif (clazz.getEnclosingClass() == null) {\n\t\t\tstr = clazz.getName().replace(\".\", \"/\");\n\t\t} else {\n\t\t\tstr = classAsFile(clazz.getEnclosingClass(), false) + \"$\" + clazz.getSimpleName();\n\t\t}\n\t\tif (suffix) {\n\t\t\tstr += \".class\";\t\t\t\n\t\t}\n\t\treturn str;  \n\t}\n\n\tpublic static byte[] classAsBytes(final Class<?> clazz) {\n\t\ttry {\n\t\t\tfinal byte[] buffer = new byte[1024];\n\t\t\tfinal String file = classAsFile(clazz);\n\t\t\tfinal InputStream in = ClassFiles.class.getClassLoader().getResourceAsStream(file);\n\t\t\tif (in == null) {\n\t\t\t\tthrow new IOException(\"couldn't find '\" + file + \"'\");\n\t\t\t}\n\t\t\tfinal ByteArrayOutputStream out = new ByteArrayOutputStream();\n\t\t\tint len;\n\t\t\twhile ((len = in.read(buffer)) != -1) {\n\t\t\t\tout.write(buffer, 0, len);\n\t\t\t}\n\t\t\treturn out.toByteArray();\n\t\t} catch (IOException e) {\n\t\t\tthrow new RuntimeException(e);\n\t\t}\n\t}\n\t\n}\n","sourceCodeStart":13,"sourceCodeEnd":45,"githubUrl":"https://github.com/frohoff/ysoserial/blob/218bcffcaaa904a4e392f0c15d9e2874533635a3/src/main/java/ysoserial/payloads/util/ClassFiles.java#L13-L45","documentation":"ClassFiles.classAsBytes() loads a class's resource (the .class file, as produced by classAsFile) via the ClassLoader and throws this IOException when getResourceAsStream returns null — i.e. the class file is not on the classpath of the loader that loaded ClassFiles itself. This happens when generating ysoserial payloads for classes not present in ysoserial's classpath.","triggerScenarios":"Calling ClassFiles.classAsBytes(SomeClass.class) where SomeClass was loaded by a parent/child loader whose resource path ('ysoserial/...' style .class path) is not resolvable by ClassFiles.class.getClassLoader(), or where the class came from generated/dynamic bytecode with no backing resource.","commonSituations":"Embedding ysoserial in an application and passing application classes not on the same classpath; shading/uber-jar packaging that drops or renames class resources; trying to serialize classes from a separate module/jar not on the runtime classpath; OSGi or app-server classloader isolation hiding the resource.","solutions":["Add the jar/module containing the target class to ysoserial's runtime classpath (e.g. java -cp ysoserial.jar:target-lib.jar ...).","Verify the resource exists: ClassFiles.class.getClassLoader().getResource(ClassFiles.classAsFile(clazz)) returns non-null before calling classAsBytes.","Ensure the same ClassLoader loads both ClassFiles and the target class; avoid cross-classloader class references in shaded/isolated environments.","If shading, keep ysoserial's original package structure so classAsFile() paths still resolve."],"exampleFix":"// before\nbyte[] bytes = ClassFiles.classAsBytes(com.example.OutOfCpClass.class); // throws\n// after\nString res = ClassFiles.classAsFile(com.example.OutOfCpClass.class);\nif (ClassFiles.class.getClassLoader().getResource(res) == null) {\n    throw new IllegalStateException(\"Add the jar containing \" + res + \" to the classpath\");\n}\nbyte[] bytes = ClassFiles.classAsBytes(com.example.OutOfCpClass.class);","handlingStrategy":"try-catch","validationCode":"public static void requireClassResource(Class<?> clazz) throws IOException {\n    String file = ClassFiles.classAsFile(clazz);\n    if (ClassFiles.class.getClassLoader().getResource(file) == null) {\n        throw new FileNotFoundException(\"Class resource not on classpath: \" + file + \" — add its jar to the runtime classpath\");\n    }\n}","typeGuard":"public static boolean isClassOnClasspath(Class<?> clazz) {\n    return ClassFiles.class.getClassLoader().getResource(ClassFiles.classAsFile(clazz)) != null;\n}","tryCatchPattern":"try {\n    byte[] bytes = ClassFiles.classAsBytes(clazz);\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"couldn't find\")) {\n        throw new IllegalStateException(\"Target class file missing from classpath: \" + e.getMessage()\n            + \" — add the containing jar to -cp\", e);\n    }\n    throw e;\n}","preventionTips":["Run payload generation with the target gadget/target library on the same classpath as ysoserial (-cp lib.jar:ysoserial.jar).","Check getResource(classAsFile(clazz)) != null before calling classAsBytes for a clear pre-flight failure.","Avoid shaded/renamed packages that break classAsFile() resource paths; verify resource presence after packaging changes.","Be aware of classloader isolation (OSGi, app servers): ensure ClassFiles and the target class share a loader that can see the resource."],"tags":["java","classpath","class-not-found"],"backgroundTag":"file-not-found","analyzedSha":"218bcffcaaa904a4e392f0c15d9e2874533635a3","analyzedAt":"2026-09-12T01:53:58.488Z","contentChangedAt":"2026-09-12T01:53:58.488Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}