{"record":{"id":"58c9fa8a8be157ad","repo":"chinabugotech/hutool","slug":"the-inputstream-must-not-be-null","errorCode":null,"errorMessage":"The InputStream must not be null","messagePattern":"The InputStream must not be null","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java","lineNumber":609,"sourceCode":"\t/**\n\t * 从流中读取对象，即对象的反序列化，读取后不关闭流\n\t *\n\t * <p>\n\t * 此方法使用了{@link ValidateObjectInputStream}中的黑白名单方式过滤类，用于避免反序列化漏洞<br>\n\t * 通过构造{@link ValidateObjectInputStream}，调用{@link ValidateObjectInputStream#accept(Class[])}\n\t * 或者{@link ValidateObjectInputStream#refuse(Class[])}方法添加可以被序列化的类或者禁止序列化的类。\n\t * </p>\n\t *\n\t * @param <T>   读取对象的类型\n\t * @param in    输入流，使用{@link ValidateObjectInputStream}中的黑白名单方式过滤类，用于避免反序列化漏洞\n\t * @param clazz 读取对象类型\n\t * @return 输出流\n\t * @throws IORuntimeException IO异常\n\t * @throws UtilException      ClassNotFoundException包装\n\t */\n\tpublic static <T> T readObj(ValidateObjectInputStream in, Class<T> clazz) throws IORuntimeException, UtilException {\n\t\tif (in == null) {\n\t\t\tthrow new IllegalArgumentException(\"The InputStream must not be null\");\n\t\t}\n\t\tif(null != clazz){\n\t\t\tin.accept(clazz);\n\t\t}\n\t\ttry {\n\t\t\t//noinspection unchecked\n\t\t\treturn (T) in.readObject();\n\t\t} catch (IOException e) {\n\t\t\tthrow new IORuntimeException(e);\n\t\t} catch (ClassNotFoundException e) {\n\t\t\tthrow new UtilException(e);\n\t\t}\n\t}\n\n\t/**\n\t * 从流中读取内容，使用UTF-8编码\n\t *\n\t * @param <T>        集合类型","sourceCodeStart":591,"sourceCodeEnd":627,"githubUrl":"https://github.com/chinabugotech/hutool/blob/8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442/hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java#L591-L627","documentation":"IoUtil.readObj(ValidateObjectInputStream, Class) deserializes an object from a validated object stream. It immediately rejects a null input stream with IllegalArgumentException(\"The InputStream must not be null\") before any deserialization is attempted.","triggerScenarios":"Calling IoUtil.readObj(null, clazz) — passing a null ValidateObjectInputStream.","commonSituations":"The stream was never opened due to an earlier failure; a resource lookup returned null; a conditional branch left the stream variable unset.","solutions":["Null-check the stream before calling readObj.","Construct the ValidateObjectInputStream in a try-with-resources so it is never null at the call site.","Use Objects.requireNonNull(stream) for an early, explicit failure."],"exampleFix":"// before\nT obj = IoUtil.readObj(vois, MyClass.class); // vois may be null\n\n// after\ntry (ValidateObjectInputStream vo = new ValidateObjectInputStream(in)) {\n    vo.accept(MyClass.class);\n    T obj = IoUtil.readObj(vo, MyClass.class);\n}","handlingStrategy":"validation","validationCode":"if (in == null) {\n    throw new IllegalArgumentException(\"ValidateObjectInputStream must not be null\");\n}\nreturn IoUtil.readObj(in, clazz);","typeGuard":"static boolean isOpenStream(ValidateObjectInputStream s) {\n    return s != null; // ObjectInputStream is open once constructed\n}","tryCatchPattern":"try {\n    return IoUtil.readObj(vois, clazz);\n} catch (IllegalArgumentException e) {\n    // stream was null: open one and retry\n}","preventionTips":["Construct the ValidateObjectInputStream in try-with-resources so it is never null at the call.","Null-check streams returned from lookups before deserializing.","Use Objects.requireNonNull(stream) to fail early with a clear message."],"tags":["io","serialization","null-safety","validation"],"backgroundTag":null,"analyzedSha":"8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442","analyzedAt":"2026-08-14T04:01:12.892Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}