Hi. I found that the component input map advertises itself as serializable, but it is really not, because somehow it seems to hold a reference to a not serializable ActionMap.
A test case, sorry about the write/read functions, they were copied from a utility class (as you can see i had to replace the logging class): package ui; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.Closeable; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.concurrent.Callable; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.InputMap; import javax.swing.JTextPane; import javax.swing.KeyStroke; import static junit.framework.Assert.*; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import util.io.IoUtils; /** * * @author i30817 */ public class ApplicationTest { public ApplicationTest() { } @BeforeClass public static void setUpClass() throws Exception { } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } /** * Test of read method, of class Application. */ @Test public void testInputMapSerialization() { JTextPane editor = new JTextPane(); InputMap map = editor.getInputMap(); KeyStroke keystroke = KeyStroke.getKeyStroke("shift SPACE"); map.put(keystroke, "test"); writeObjects("InputMap", map); InputMap other = readObject("InputMap", new Callable(){ public Object call() throws Exception { return new InputMap(); } }); assertEquals("test", other.get(keystroke)); } /** * If possible reads an object, if not tries to instanciate the * object with the given Callable. This allows lazy instantiation. * This funtion can only read 1 object per file, to allow encapsulation * of the inputstreams. * If an exception occurs in the lazy instantiation it returns null. * Remember that if using Externalizable transient fields/static scopes * fields ARE initalized. The use of the default constructor assures that. * The order of inicialization is: * Externalizable : default constructor, readExternal * Serializable : first non-serializable super class default constructor, * readObject * So with externalizable you need to be carefull to replace the super state * and not to use it in the default constructor. * In serializable, you need to replace the constructor state. */ @SuppressWarnings(value = "unchecked") public static <T> T readObject(String objectLocation, Callable t) { ObjectInputStream s = null; try { s = new ObjectInputStream(new BufferedInputStream(new FileInputStream(objectLocation))); return (T) s.readObject(); } catch (Throwable ex) { Logger.getLogger(IoUtils.class.getName()).log(Level.WARNING, "Couldnt read object", ex); if (t != null) { try { return (T) t.call(); } catch (Throwable e) { Logger.getLogger(ApplicationTest.class.getName()).log(Level.SEVERE, "Couldnt create object", e); } } } finally { close(s); } return null; } /** * If possible writes objects. Disallows null objects */ public static void writeObjects(String objectLocation, Serializable... obj) { ObjectOutputStream s = null; try { s = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(objectLocation))); for (Serializable a : obj) { if (a != null) { s.writeObject(a); } } s.flush(); } catch (Throwable ex) { Logger.getLogger(ApplicationTest.class.getName()).log(Level.SEVERE, "Couldnt write object", ex); } finally { close(s); } } /** * Close closeables. Use this in a finally clause. */ public static void close(Closeable... closeables) { for (Closeable c : closeables) { if (c != null) { try { c.close(); } catch (Throwable ex) { Logger.getLogger(ApplicationTest.class.getName()).log(Level.WARNING, "Couldnt close Closeable", ex); } } } } }