0

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!

SudoTronic
  • 13
  • 6
  • There is a flag you can pass to the JVM to get it to tell you what isn't serializable: https://stackoverflow.com/a/1660583/3788176 – Andy Turner Feb 02 '20 at 07:57
  • I appreciate the suggestion in all but I'm not quite sure how that works? I've never learned about "Flags", I guess Ill try out -Dsun.io.serialization.extendedDebugInfo=true though, – SudoTronic Feb 02 '20 at 08:00
  • The superclasses of LinkedInUser and the closure of their fields' types also need to be serializable. The exception is saying that *something* is not serializable, and it won't be lying. – Stephen C Feb 02 '20 at 08:06
  • @Stephen C I do understand that LinkedInUser and its superclass (In this case UserAccount) need to be implementing serializable, however, What do you mean by "The closure of its fields types"? – SudoTronic Feb 02 '20 at 08:09
  • 1
    @N00b He means that if you follow the links from your `LinkedInUser` up to its superclasses and then follow the links from every field to its class recursively, everything has to be `Serializable`. – chrylis -cautiouslyoptimistic- Feb 02 '20 at 08:21
  • 2
    @chrylis-onstrike- more precisely, every field's *value* has to be serializable. Provided a non-serializable field's value is null, or it's an instance of a serializable subclass, it can still be serialized. – Andy Turner Feb 02 '20 at 09:40
  • 1
    The exception message *tells* you which class wasn't serializable. Just print it. As a general rule you should not substitute your own text for the text of any exception. – user207421 Feb 02 '20 at 11:36
  • @user207421 Ok, ill get rid of the custom messages. – SudoTronic Feb 02 '20 at 16:30
  • @user207421 You are awesome, Ill always take the advice to just print out the stack trace, what was I thinking? I figured it out very quickly after that. TYSM. – SudoTronic Feb 02 '20 at 16:45
  • @SudoTronic wrt your question about gravestone OCR: I would suggest the most reliable method would be to get humans to do the "OCR" (think: mechanical turk). You may be able to find an automated way to do it, but humans would allow you to prove the viability of the concept, without spending a lot of time building something that only maybe worthwhile in the end. Good luck. – Andy Turner Aug 13 '20 at 17:22
  • @AndyTurner Thanks! – SudoTronic Aug 17 '20 at 19:59

1 Answers1

0

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;
Piotr Niewinski
  • 1,298
  • 2
  • 15
  • 27