【问题标题】:java.io.NotSerializableException: java.util.HashMap$Valuesjava.io.NotSerializableException: java.util.HashMap$Values
【发布时间】:2023-10-22 00:28:01
【问题描述】:

堆栈跟踪:

org.jboss.remoting.InvocationFailureException: Unable to perform invocation;
nested exception is: java.io.WriteAbortedException: writing aborted;
java.io.NotSerializableException: java.util.HashMap$Values

遗憾的是,日志没有显示出现序列化问题的行或类,但调试 ESB 直到出现问题的步骤所有使用的 HashMap 都只有可序列化的对象,如 String、Long 和 Date!

另外,调用远程方法时也会出现问题,是无效的。

你以前见过这样的事情吗?

【问题讨论】:

    标签: java serialization map hashmap esb


    【解决方案1】:

    找到问题了!

    远程服务试图抛出一个封装来自HashMap.values()的字符串集合的异常:

    if (!identifiersMap.isEmpty()) {
        context.setRollbackOnly();
    
        BusinessException e = new BusinessException();
        e.setValues(identifiersMap.values()); // here is where the problem is
        throw e;
    }
    

    HashMap 有一个名为Values (as you can see here) 的内部类,它是Collection 的一个实现并且不可序列化。所以,抛出一个内容为HashMap.values()的异常,远程方法将改为抛出一个序列化异常!

    例如,

    ArrayList 是可序列化的,可用于解决问题。工作代码:

    if (!identifiersMap.isEmpty()) {
        context.setRollbackOnly();
    
        BusinessException e = new BusinessException();
        e.setValues(new ArrayList(apIdentifiersMap.values())); // problem fixed
        throw e;
    }
    

    我的情况,远程方法是无效的,它正在抛出一个异常,但请注意:

    如果远程服务返回一个HashMap$Values实例也会发生,例如:

    return hashMap.values(); // would also have serialization problems
    

    再一次,解决方案是:

    return new ArrayList(hashMap.values()); // problem solved
    

    【讨论】:

    • +1 由于源是地图,也许您可​​以允许e.setValues(identifiersMap);,因为地图应该是可序列化的。
    • @PeterLawrey 还有一个很好的解决方案,彼得,一如既往。但我宁愿不更改setValues 方法的签名,因为它在其他地方被使用和处理。谢谢你的贡献。
    • 我遇到了同样的问题,但是使用 keySet,谢谢您的提示!