In my program, I have a FacebookUser class that has an ArrayList of all of that user's friends. All of those friends may also have friends. I am using recursion to get a new ArrayList that contains all of the user's friends and all of the user's friends' friends and so on. I also serialized the FacebookUser class so I can save the data. Without the new recursive method, I can serialize without error and the data persists over executions. With the recursive method, though, I get an InvalidClassException. It shows that the exception is at the line that uses the ObjectInputStream to get the FacebookUser from memory.
I'm not understanding why the new method is causing the exception to be thrown from another method. I believe the problem lies only in the FacebookUser.java class (since getRecommendations is recursive method) but I thought it'd be best to also show the UserAccount.java class since the former extends the latter. Any help will be appreciated. Thank you.
Execution:
Exception in thread "main" java.io.InvalidClassException: FacebookUser; local class incompatible: stream classdesc serialVersionUID = 4110981517967863740, local class serialVersionUID = 5032562666539812166
at java.base/java.io.ObjectStreamClass.initNonProxy(Unknown Source)
at java.base/java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.base/java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.base/java.io.ObjectInputStream.readObject0(Unknown Source)
at java.base/java.io.ObjectInputStream.readObject(Unknown Source)
at FacebookUser.readFile(FacebookUser.java:157)
at DriverClass.main(DriverClass.java:12)
FacebookUser.Java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
public class FacebookUser extends UserAccount implements Serializable{
private String passwordHint;
private ArrayList<FacebookUser> friends;
public FacebookUser(String username, String password) {
super(username, password);
friends = new ArrayList<FacebookUser>();
}
@Override
public void getPasswordHelp() {
System.out.println("Password Hint: " + passwordHint);
}
public void getPasswordHelp(String username) {
if (friends.size() == 0) {
System.out.println("There is no user with that username.");
} else {
for (int i = 0; i < friends.size(); i++) {
if (friends.get(i).toString().equals(username)) {
friends.get(i).getPasswordHelp();
break;
}
if (i == friends.size() - 1) {
System.out.println("There is no user with that username.");
break;
}
}
}
}
void setPasswordHint(String hint) {
passwordHint = hint;
}
void friend(FacebookUser newFriend) {
if (friends.contains(newFriend)) {
System.out.println("That person is already your friend.");
} else {
friends.add(newFriend);
}
}
void friend(String username) {
Scanner s = new Scanner(System.in);
if (friends.size() == 0) {
System.out.println("Please create a password: ");
String password = s.nextLine();
System.out.println("Please create a password hint: ");
String passHint = s.nextLine();
FacebookUser fbu = new FacebookUser(username, password);
fbu.setPasswordHint(passHint);
friends.add(fbu);
} else {
for (int i = 0; i < friends.size(); i++) {
if (friends.get(i).toString().equals(username)) {
System.out.println("That person is already your friend.");
break;
}
if (i == friends.size() - 1) {
System.out.println("Please create a password: ");
String password = s.nextLine();
System.out.println("Please create a password hint: ");
String passHint = s.nextLine();
FacebookUser fbu = new FacebookUser(username, password);
fbu.setPasswordHint(passHint);
friends.add(fbu);
break;
}
}
}
}
void defriend(FacebookUser formerFriend) {
if (friends.contains(formerFriend)) {
friends.remove(formerFriend);
} else {
System.out.println("That person is not your friend.");
}
}
void defriend(String username) {
Scanner s = new Scanner(System.in);
if (friends.size() == 0) {
System.out.println("That person is not your friend.");
} else {
for (int i = 0; i < friends.size(); i++) {
if (friends.get(i).toString().equals(username)) {
System.out.println("Password for " + username + ": ");
String passw = s.nextLine();
if (friends.get(i).getPassword().equals(passw)) {
friends.remove(i);
break;
} else {
System.out.println("Incorrect Password");
break;
}
}
if (i == friends.size() - 1) {
System.out.println("That person is not your friend.");
break;
}
}
}
}
ArrayList<FacebookUser> getRecommendations(FacebookUser friend) {
ArrayList<FacebookUser> recFriends = new ArrayList<FacebookUser>();
for (int i = 0; i < friend.getFriends().size(); i++) {
for (int j = 0; j < recFriends.size(); j++) {
for (int k = 0; k < recFriends.size(); k++) {
if (recFriends.get(j).equals(recFriends.get(k))) {
recFriends.remove(j); // This removes any duplicate friends so there won't be an infinite loop.
break;
}
}
}
recFriends.addAll(friend.getFriends().get(i).getRecommendations(friend)); // This adds the friends' friends' friends and so on into the ArrayList.
}
return recFriends;
}
ArrayList<FacebookUser> getFriends() {
ArrayList<FacebookUser> friendsCopy = new ArrayList<FacebookUser>();
for (int i = 0; i < friends.size(); i++) {
friendsCopy.add(friends.get(i));
}
Collections.sort(friendsCopy, new Comparator<FacebookUser>() {
@Override
public int compare(FacebookUser fb1, FacebookUser fb2) {
return fb1.toString().compareToIgnoreCase(fb2.toString());
}
});
return friendsCopy;
}
public static void writeToFile(FacebookUser facebookUser) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("FacebookUser.bin"));
oos.writeObject(facebookUser); // This saves the data.
}
public static FacebookUser readFile() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("FacebookUser.bin"));
FacebookUser facebookUser = (FacebookUser) ois.readObject(); // This reads in the data which is called in the DriverClass class line 12.
return facebookUser;
}
}
UserAccount.java
import java.io.Serializable;
public abstract class UserAccount implements Serializable{
private String username;
private String password;
private boolean active;
public UserAccount(String username, String password) {
this.username = username;
this.password = password;
active = true;
}
public boolean checkPassword(String password) {
if (password.equals(this.password)) {
return true;
} else {
return false;
}
}
public void deactivateAccount() {
active = false;
}
public String getPassword() {
return password;
}
public String toString() {
return username;
}
public boolean checkActive() {
if (active == true) {
return true;
} else {
return false;
}
}
public abstract void getPasswordHelp();
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((username == null) ? 0 : username.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
UserAccount other = (UserAccount) obj;
if (username == null) {
if (other.username != null)
return false;
} else if (!username.equals(other.username))
return false;
return true;
}
}
DriverClass.java
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;
public class DriverClass {
public static void main(String[] args) throws IOException, ClassNotFoundException {
int choice = 0;
String username;
FacebookUser fu0;
try {
fu0 = FacebookUser.readFile();
} catch (FileNotFoundException e) {
fu0 = new FacebookUser("Robert", "password1");
}
while (choice != 5) {
System.out.println(
"1. List Users \n2. Add a User \n3. Delete a User \n4. Get Password Hint \n5. Get Recommendations \n6. Quit");
Scanner s = new Scanner(System.in);
choice = s.nextInt();
switch (choice) {
case 1:
System.out.println(fu0.getFriends());
break;
case 2:
System.out.println("Username: ");
s.nextLine();
username = s.nextLine();
fu0.friend(username);
break;
case 3:
System.out.println("Username: ");
s.nextLine();
username = s.nextLine();
fu0.defriend(username);
break;
case 4:
System.out.println("Username: ");
s.nextLine();
username = s.nextLine();
fu0.getPasswordHelp(username);
break;
case 5:
System.out.println(fu0.getRecommendations(fu0));
break;
case 6:
FacebookUser.writeToFile(fu0);
break;
}
}
}
}