chinabugotech/hutool · error · IllegalArgumentException
The InputStream must not be null
Error message
The InputStream must not be null
What it means
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.
Source
Thrown at hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java:609
/**
* 从流中读取对象,即对象的反序列化,读取后不关闭流
*
* <p>
* 此方法使用了{@link ValidateObjectInputStream}中的黑白名单方式过滤类,用于避免反序列化漏洞<br>
* 通过构造{@link ValidateObjectInputStream},调用{@link ValidateObjectInputStream#accept(Class[])}
* 或者{@link ValidateObjectInputStream#refuse(Class[])}方法添加可以被序列化的类或者禁止序列化的类。
* </p>
*
* @param <T> 读取对象的类型
* @param in 输入流,使用{@link ValidateObjectInputStream}中的黑白名单方式过滤类,用于避免反序列化漏洞
* @param clazz 读取对象类型
* @return 输出流
* @throws IORuntimeException IO异常
* @throws UtilException ClassNotFoundException包装
*/
public static <T> T readObj(ValidateObjectInputStream in, Class<T> clazz) throws IORuntimeException, UtilException {
if (in == null) {
throw new IllegalArgumentException("The InputStream must not be null");
}
if(null != clazz){
in.accept(clazz);
}
try {
//noinspection unchecked
return (T) in.readObject();
} catch (IOException e) {
throw new IORuntimeException(e);
} catch (ClassNotFoundException e) {
throw new UtilException(e);
}
}
/**
* 从流中读取内容,使用UTF-8编码
*
* @param <T> 集合类型View on GitHub (pinned to 8870454b2a)
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.
Example fix
// before
T obj = IoUtil.readObj(vois, MyClass.class); // vois may be null
// after
try (ValidateObjectInputStream vo = new ValidateObjectInputStream(in)) {
vo.accept(MyClass.class);
T obj = IoUtil.readObj(vo, MyClass.class);
} Defensive patterns
Strategy: validation
Validate before calling
if (in == null) {
throw new IllegalArgumentException("ValidateObjectInputStream must not be null");
}
return IoUtil.readObj(in, clazz); Type guard
static boolean isOpenStream(ValidateObjectInputStream s) {
return s != null; // ObjectInputStream is open once constructed
} Try / catch
try {
return IoUtil.readObj(vois, clazz);
} catch (IllegalArgumentException e) {
// stream was null: open one and retry
} Prevention
- 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.
When it happens
Trigger: Calling IoUtil.readObj(null, clazz) — passing a null ValidateObjectInputStream.
Common situations: The stream was never opened due to an earlier failure; a resource lookup returned null; a conditional branch left the stream variable unset.
Related errors
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/58c9fa8a8be157ad.
Report an issue: GitHub.