Hi - This is my understanding and please forgive me if I state the obvious.
Java runs on a Virtual Machine (VM), i.e. it is not compiled code native of the systems architecture, and runs in an environment that sits on top of the operating system. Java web applications can be run across multiple VMs which may (or may not) be on different machines - the management of this is done by the Web/Application server - the container.
In order to migrate or move a session to a different VM - without loosing the session state (attributes etc.) - the container needs to ensure that the VM on the receiving side has everything it needs to keep the session going and make it look to the user like nothing has happend.
Java web applications can be run across multiple VMs which may (or may not) be on different machines
Graham is on the right track, but this sentence is a bit misleading. A web app is rarely run across multiple JVMs, it's more likely run on multiple JVMs. That means the same web app runs on several servers. If the servers are clustered, then the sessions are distributed, meaning that each session lives on several machines, although only one of them actually serves the client. But if that machine goes down, the next request can go to any other of the machines in the cluster, and -since the session has been duplicated to all the machines in the cluster- the request can be handled as if it was on the original machine, because the session is there in full. For that to work, all objects in a session need to implement the Serializable interface.