Is InputMap serializable or not?

Paulo Levi i30817 at gmail.com
Tue Oct 21 18:04:02 UTC 2008


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);
                }
            }
        }
    }
}



More information about the core-libs-dev mailing list