Eelco took my original ten minute hack and ran with it, and has produced something that covers a lot more edge cases. It handles anonymous inner classes, externalizables, things with custom writeObject() functions and a bunch of other stuff. It also plays nicely with SecurityManagers. You can find the code in Wicket 1.3’s SerializableChecker.java. It has a couple of custom Wicket bits, but would be completely trivial to strip those out if you wanted to use this somewhere else. At about 700 lines, it’s a bit more complicated than we both expected it to be, but it’s pretty robust. Good work Eelco!
Ever had a java.io.NotSerializableException in your code and found it very hard to debug? The JVM stack trace is nearly useless, telling you which code triggered the serialization, but not what it is trying to serialize.
Particularly tedious are HTTP sessions that refuse to serialize. In Wicket we store detached components in the session between requests. If you run a clustered app-server with session replication and add objects to your components that don’t implement Serializable, you’re toast. To avoid you deploying something with this issue and getting fired, we have a setting in development mode that tries to serialize the session on every page request. Unfortunately, although it helps you spot this problem early, it’s lumbered with the same unhelpful java.io.NotSerializableException as everything else in the world.
How do we make these issues easier to debug? Well, I’ve just written an ObjectOutputStream subclass which produces output like this:
java.lang.RuntimeException: Unable to serialize class: com.foo.C Field hierarchy is: Class com.foo.A public com.foo.B myFieldForB public com.foo.C myFieldForC < ----- field that is not serializable at DebuggingObjectOutputStream.writeObjectOverride(DebuggingObjectOutputStream.java:105) at DebuggingObjectOutputStream.writeObjectOverride(DebuggingObjectOutputStream.java:96) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:298) at DebuggingObjectOutputStream.main(DebuggingObjectOutputStream.java:28) Caused by: java.io.NotSerializableException: com.foo.C ... 4 more