0

I am trying to serialize a JFrame , but its returning a java.io.NotSerializableException. I am designing an application and the following was just a poc on trying to serialize a jframe. The serialization is working fine for the employee subclass, but its not working for the swing JFrame. I am unable to understand why, since all the fields are static. Could someone please throw some light on this? Here is my code:

        import java.awt.event.WindowAdapter;
        import java.awt.event.WindowEvent;
        import java.awt.event.WindowListener;
        import java.io.File;
        import java.io.FileInputStream;
        import java.io.FileNotFoundException;
        import java.io.FileOutputStream;
        import java.io.IOException;
        import java.io.ObjectInputStream;
        import java.io.ObjectOutputStream;
        import java.util.ArrayList;
        import java.util.LinkedHashMap;
        import java.util.logging.Level;
        import java.util.logging.Logger;
        import javax.swing.JOptionPane;

        /**
        *
        * @author SamDescartes
        */
        public class SerDemo extends javax.swing.JFrame implements java.io.Serializable{

        //private static final long serialVersionUID = 1L;
        private  static int empNo;
        private static final String fileName="C:\\Users\\Public\\Documents\\AtlizerProjects\\tmp\\SerDemo.ser";
        /**
        * Creates new form SerDemo
        */
        public SerDemo() {

        initComponents();
        initMine();
        }

        /**
        * This method is called from within the constructor to initialize the form.
        * WARNING: Do NOT modify this code. The content of this method is always
        * regenerated by the Form Editor.
        */
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
        private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jTextField1 = new javax.swing.JTextField();
        jTextField2 = new javax.swing.JTextField();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);

        jLabel1.setText("Name: ");

        jLabel2.setText("Aadhar No:");

        jButton1.setText("Ok");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton1ActionPerformed(evt);
            }
        });

        jButton2.setText("Show");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton2ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                .addGroup(layout.createSequentialGroup()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 188, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGroup(layout.createSequentialGroup()
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(layout.createSequentialGroup()
                    .addComponent(jButton1)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jButton2))
                    .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, 188, javax.swing.GroupLayout.PREFERRED_SIZE))))
            .addContainerGap(11, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
            .addGap(19, 19, 19)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jLabel1)
                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jLabel2)
                .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addGap(18, 18, 18)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jButton1)
                .addComponent(jButton2))
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
        }// </editor-fold>                        

        private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        e=new Employee();
        e.name=jTextField1.getText();
        e.aadharNo=jTextField2.getText();
        this.empNo=this.empNo+1;
        String empFileName="employee"+this.empNo;
        eMap.put(this.empNo,empFileName);
        try{
            FileOutputStream fileOut = new FileOutputStream("C:\\Users\\Public\\Documents\\AtlizerProjects\\tmp\\"+empFileName);
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(e);
            out.close();
            fileOut.close();
            System.out.println("Serialized data is saved in C:\\Users\\Public\\Documents\\AtlizerProjects\\tmp\\"+empFileName);
        }catch(IOException ex){
            Logger.getLogger(SerDemo.class.getName()).log(Level.SEVERE, null, ex);
        }
        }                                        

        private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        try{
         for(int i=1;i<=this.empNo;i++){
             String eFile=(String) eMap.get(i);
             System.out.println(eMap);
             Employee em=null;
             FileInputStream fileIn = new FileInputStream("C:\\Users\\Public\\Documents\\AtlizerProjects\\tmp\\"+eFile);
             ObjectInputStream in = new ObjectInputStream(fileIn);
             em = (Employee) in.readObject();
             in.close();
             fileIn.close();
             System.out.println(em.aadharNo+","+em.name);
         }
        }catch(  IOException | ClassNotFoundException ex){
          Logger.getLogger(SerDemo.class.getName()).log(Level.SEVERE, null, ex);
        }
        }                                        

        /**
        * @param args the command line arguments
        */
        public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        //        try {
        //            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
        //                if ("Nimbus".equals(info.getName())) {
        //                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
        //                    break;
        //                }
        //            }
        //        } catch (ClassNotFoundException ex) {
        //            java.util.logging.Logger.getLogger(SerDemo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        //        } catch (InstantiationException ex) {
        //            java.util.logging.Logger.getLogger(SerDemo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        //        } catch (IllegalAccessException ex) {
        //            java.util.logging.Logger.getLogger(SerDemo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        //        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        //            java.util.logging.Logger.getLogger(SerDemo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        //        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
            try{
                File f;
                f = new File(SerDemo.fileName);
                if(f.isFile()){
                SerDemo ser=null;
                FileInputStream fileIn = new FileInputStream("C:\\Users\\Public\\Documents\\AtlizerProjects\\tmp\\serDemo.ser");
                ObjectInputStream ois = new ObjectInputStream(fileIn);
                ser = (SerDemo) ois.readObject();
                ois.close();
                fileIn.close();
                ser.setVisible(true);
                }else{
                   new SerDemo().setVisible(true); 
                }
            }catch(Exception ex){
                 Logger.getLogger(SerDemo.class.getName()).log(Level.SEVERE, null, ex);
            }

            }
        });
        }
        // Variables declaration - do not modify                     
        private javax.swing.JButton jButton1;
        private javax.swing.JButton jButton2;
        private javax.swing.JLabel jLabel1;
        private javax.swing.JLabel jLabel2;
        private javax.swing.JTextField jTextField1;
        private javax.swing.JTextField jTextField2;
        // End of variables declaration                   
        Employee e;
        ArrayList<Employee> eList;
        LinkedHashMap eMap;
        private void initMine() {
        eList=new ArrayList<>();
        eMap=new LinkedHashMap();
        WindowListener exitListener = new WindowAdapter(){
          @Override
          public void windowClosing(WindowEvent e){
           int confirm = JOptionPane.showOptionDialog(null, "Are You Sure to Close Application?", "Exit Confirmation", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);   
           System.out.println(confirm);
           if(confirm==0){
               try{
             FileOutputStream serDemo =new FileOutputStream("C:\\Users\\Public\\Documents\\AtlizerProjects\\tmp\\serDemo.ser");
             ObjectOutputStream oos = new ObjectOutputStream(serDemo);
             oos.writeObject(this);
             oos.close();
             serDemo.close();  
               } catch (FileNotFoundException ex) {
               Logger.getLogger(SerDemo.class.getName()).log(Level.SEVERE, null, ex);
               } catch (IOException ex) {
               Logger.getLogger(SerDemo.class.getName()).log(Level.SEVERE, null, ex);
               }
               System.exit(0);
           }else{
               System.out.println("Hello Again");
           }
          }
        };
        addWindowListener(exitListener);

        }


        }

The error message encountered is:

    Sep 19, 2013 5:25:33 PM com.sl.app.SerDemo$4 windowClosing
    SEVERE: null
    java.io.NotSerializableException: com.sl.app.SerDemo$4
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
        at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
        at com.sl.app.SerDemo$4.windowClosing(SerDemo.java:231)
        at java.awt.Window.processWindowEvent(Window.java:2051)
        at javax.swing.JFrame.processWindowEvent(JFrame.java:296)
        at java.awt.Window.processEvent(Window.java:2009)
        at java.awt.Component.dispatchEventImpl(Component.java:4861)
        at java.awt.Container.dispatchEventImpl(Container.java:2287)
        at java.awt.Window.dispatchEventImpl(Window.java:2719)
        at java.awt.Component.dispatchEvent(Component.java:4687)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:729)
        at java.awt.EventQueue.access$200(EventQueue.java:103)
        at java.awt.EventQueue$3.run(EventQueue.java:688)
        at java.awt.EventQueue$3.run(EventQueue.java:686)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
        at java.awt.EventQueue$4.run(EventQueue.java:702)
        at java.awt.EventQueue$4.run(EventQueue.java:700)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:699)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
vhora
  • 320
  • 2
  • 16
  • The JVM is attempting to serialize one of your anonymous classes, but they're not declared `Serializable`. Use an IDE to figure out which one is `$4`. – chrylis -cautiouslyoptimistic- Sep 19 '13 at 12:45
  • I am using the NetBeans IDE, but I am unable to figure out the 'anonymous class', I thought it could be the group layout and changed it to gridbag layout, but still getting the same error.. any idea on how to find out which class it is, i.e $4? – vhora Sep 19 '13 at 13:18
  • It should be the fourth anonymous class in text order. Disassemble `SerDemo$4.class` if you can't figure it out. – chrylis -cautiouslyoptimistic- Sep 19 '13 at 13:20
  • Ok I solved this issue.., the problem was that I had doing the serialization inside the exitListener=new WindowAdapter() declaration. I wrote the serialization code in a separate method and called it from the exitListener. But the next issue is that none of the buttons are working. Do the listeners not get serialized along with the JFrame? – vhora Sep 19 '13 at 13:31
  • Check the inheritance hierarchy for `ActionListener`. – chrylis -cautiouslyoptimistic- Sep 19 '13 at 13:34
  • I am still a beginner in swing, could you please clarify? – vhora Sep 19 '13 at 13:39
  • `ActionListener` doesn't extend `Serializable`, and since the listeners depend on so much internal runtime state anyway, it's probably impossible to serialize them even in theory. – chrylis -cautiouslyoptimistic- Sep 19 '13 at 13:41
  • *"I am trying to serialize a JFrame"* Why? I'd tend to just [save particular settings](http://stackoverflow.com/a/7778332/418556). *"I am designing an application and the following was just a poc on trying to serialize a jframe."* What does 'poc' mean? – Andrew Thompson Sep 19 '13 at 16:32
  • poc means proof of concept, sorry if I didnt make myself clearer before, and yes saving particular settings makes more sense, but I was just trying to see if we can serialize a JFrame successfully or not, and we can but at the cost of action listeners. – vhora Sep 20 '13 at 06:37

0 Answers0