java.io.NotSerializableException: java.util.HashMap$Values

falsarella picture falsarella · Sep 9, 2013 · Viewed 12.1k times · Source

Stacktrace:

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

Sadly, the log doesn't show the line or the class where the serialization problem occurs, but debugging the ESB until the step where problem occurs all the HashMap's that are used have only Serializable objects like String, Long and Date!

Also, the problem occurs when calling a remote method, which is void.

Have you seen something like this before?

Answer

falsarella picture falsarella · Sep 9, 2013

Found the problem!

The remote service was trying to throw an Exception encapsulating a Collection of String from HashMap.values():

if (!identifiersMap.isEmpty()) {
    context.setRollbackOnly();

    BusinessException e = new BusinessException();
    e.setValues(identifiersMap.values()); // here is where the problem is
    throw e;
}

HashMap has an inner class named Values (as you can see here), which is an implementation of Collection and is NOT Serializable. So, throwing an exception having the content of HashMap.values(), the remote method will throw a serialization exception instead!

ArrayList, for example, is Serializable and could be used to resolve the issue. Working code:

if (!identifiersMap.isEmpty()) {
    context.setRollbackOnly();

    BusinessException e = new BusinessException();
    e.setValues(new ArrayList(apIdentifiersMap.values())); // problem fixed
    throw e;
}

My case, the remote method was void and it was throwing an Exception, but note:

It will also occur if the remote service return a HashMap$Values instance, for example:

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

Once again, the solution would be:

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