Search code examples
javaexceptionarraylistio

( SOLVED ) Serializing (Writing) an Arraylist full of Objects keeps throwing "NotSerializableException"


I am a Java student that is having a bit of trouble. So I am writing a program named "LinkedInCLI" which uses 4 different classes:

  1. UserAccount
  2. LinkedInUser
  3. LinkedInException (Custom Exception)
  4. LinkedInCLI

I am currently writing the "LinkedInCLI" class to preform various functions. One of these functions is to add a "User" to an Arraylist of users, the object LinkedInUser is defind by the name, password of the "Account" and the "Type of account"

Really they are just all strings that determine the information about the "User". Its constructor looks like this.

public class LinkedInUser extends UserAccount implements  java.io.Serializable ,Comparable<LinkedInUser>{

public LinkedInUser(String user, String pass , String type) {
    super(user, pass, type);
}

Ok so on to the question already:

Once I have created these users, they go onto an ArrayList of LinkedInUsers that looks like this.

private static List<LinkedInUser> users = new ArrayList<>();

This is located inside of LinkedInCLI and is NOT inside of the main method. it is located next to the private fields and such.

I want to serialize the ArrayList into a .DAT file, once I have done this I want to terminate my program and execute it again and read the previous ArrayList from the program execution. Once I have done this the ArrayList should be the same as the execution before it.

But I keep encountering a "NotSerializableException". I have written the ObjectOutputStream and ObjectInputStream already, and they look correctly written, but something is wrong and it will not write the object. This is what my streams look like

ObjectOutputStream oos = null;

             try
                {

                 // CREATE file path and display it

                new File(PATH).mkdirs();


                System.out.println(PATH);


                 // SAVE arraylist
                    oos = new ObjectOutputStream(new FileOutputStream(PATHPLUSNAME)); 

                    oos.writeObject(users);
                    System.out.println("Writing users to file");
                    System.out.println(": " + users);



                //CLOSE resources
                    oos.flush();
                    oos.close(); 




                } 
             catch (FileNotFoundException FNFO) {
                    System.out.println("The file was not found");
                }
            catch(NotSerializableException NSEO) {
                System.out.println("Type is not serializable");
            }
                catch (IOException IOEXO) { 
                    System.out.println("Could not serialize users"); 
                } 

 try { 

        LinkedInUser test = new LinkedInUser();

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PATHPLUSNAME)); 

        ArrayList usersCopied = (ArrayList<LinkedInUser>) ois.readObject();



        users.addAll(usersCopied);



        ois.close(); 

    }
    catch (FileNotFoundException FNFI) {
        System.out.println("The file was not found");
    }
    catch (IOException IOEXI) { 
        System.out.println("Could not Deserialize users"); 
    } 
    catch (ClassNotFoundException CLNI) {
        System.out.println("Could not find class");
    }

My question really is: Why the heck does this exception keep throwing? At first, it was just an IOException but then I looked up the sub-exceptions and tried them all, and figured out it was specifically the "NotSerializableException".

NOTE: All the other classes implement serializable as well...

---------------------------------------------------------------------------- This issue has been solved, the issue was that my UserAccount Method implements serializable, BUT it also implemented comparable, which DOES NOT implement serializable, I found that out by looking at the oracle document, also. There were some stray scanners at the top of the UserAccount class that were not serializable as well.

To any that help brainstorm this issue with me, thank you. You guys are awesome!


Solution

  • I have checked your code without super class UserAccount - it works fine.

    Since you didn't provide the source code of UserAccount then there are two possibilities:

    First is that UserAccount implements java.io.Serializable indeed as you said. In such case make sure that all of fields of your super class (or super classes of those fields and so on..) do implement java.io.Serializable as well.

    Second - when in fact you forgot to implement Serializable or somehow can't. In such case to extend UserAccount you would also need to add no-arg constructor to that class. In other words you would need no-arg constructor for first nonserializable super class of your class.

    The following table explains it very clearly:

    Summary of possible cases and solutions Source: Image

    Tip: If it still doesn't work for you, then you can try marking fields of UserAccount class as transient and then compile to see which one is causing problems. Those fields will be not serialized.

    transient String field;