I am writing a simple instant messaging program using JavaFX and have encountered an an End Of File exception and after hours of debugging I cannot find a solution.
My program is written in two parts, the client and the server. They send serialized objects to each other containing all the necessary information to complete the required action. I was adding additional features to my program when I started getting this error in the server. I have since removed all of the additional code but am still getting this error message. I don't understand why I'm getting this error as neither the client nor the server are sending a message meaning there's no file to reach the end of??
I comment out the line where I call the method "sendMessage()" and that seems to solve the issue but I need this method to work.
Bellow is a copy of the server class
package instachatfx.server;
public class ServerMain {
private static HashSet<ObjectOutputStream> writers;
private static ArrayList<User> users = new ArrayList<>();
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
writers = new HashSet<>();
try (ServerSocket listener = new ServerSocket(Constants.
while (true) {
new Handler(listener.accept()).start();
}
} catch (IOException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static class Handler extends Thread {
private Socket socket;
private ObjectInputStream input;
private OutputStream os;
private ObjectOutputStream output;
private InputStream is;
private User user;
private String code;
public Handler(Socket socket) throws IOException {
this.socket = socket;
}
@Override
public void run() {
try {
is = socket.getInputStream();
input = new ObjectInputStream(is);
os = socket.getOutputStream();
output = new ObjectOutputStream(os);
while (socket.isConnected()) {
System.out.println("Waiting for packet...");
Packet inputmsg = (Packet) input.readObject();
if (inputmsg != null) {
switch (inputmsg.getHeader()) {
case REGISTER:
System.out.println("Case: REGISTER");
registerUser((User) inputmsg.getContent());
break;
case LOGIN:
System.out.println("Case: LOGIN");
loginUser((User) inputmsg.getContent());
break;
case CODE:
System.out.println("Case: CODE");
if (((String) inputmsg.getContent()).equalsIgnoreCase(code)) {
Constants.getDBManager().createNewUser(user);
loginUser(user);
} else {
sendMessage(PacketHeader.INCORRECT_CODE, "Incorrect code");
}
break;
case MESSAGE:
System.out.println("Case: MESSAGE");
sendToAll(inputmsg);
System.out.println(((Message) inputmsg.getContent()).getUser().toString() + ": " + ((Message) inputmsg.getContent()).getContent());
break;
default:
throw new HeaderNotFoundException("Server has no case for: " + inputmsg.getHeader().name());
}
}
}
} catch (SocketException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (HeaderNotFoundException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (EOFException ex)
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
} finally {
closeConnections();
}
}
private void sendToAll(Packet msg) throws IOException {
System.out.println("Send to all: " + msg.getHeader());
((Message) msg.getContent()).setUsers(users);
for (ObjectOutputStream writer : writers) {
writer.writeObject(msg);
writer.flush();
writer.reset();
}
}
private void sendToOthers(Packet msg) throws IOException {
System.out.println("Send to others: " + msg.getHeader());
((Message) msg.getContent()).setUsers(users);
for (ObjectOutputStream writer : writers) {
if (output != writer) {
writer.writeObject(msg);
writer.flush();
writer.reset();
}
}
}
/**
* Logs in a user
* @param u the user to be logged in
*/
private void loginUser(User u) {
try {
User us;
if ((us = Constants.getDBManager().loginUser(u)) != null) {
System.out.println("User found in database");
user = us;
writers.add(output);
users.add(user);
LoginMsg msg = new LoginMsg(user, users);
sendMessage(PacketHeader.LOGIN_SUCCESSFUL,
sendToOthers(new Packet(PacketHeader.MESSAGE, new Message(user.toString() + " has joined the chat", new User("SERVER", null))));
} else {
sendMessage(PacketHeader.LOGIN_FAIL, "Please check email and password");
}
} catch (IOException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void registerUser(User u) throws IOException{
user = u;
if (Constants.getDBManager().checkDeuplicateEmail(u.getEmail())) {
sendMessage(PacketHeader.EMAIL_ALREADY_USED, "The email address " + u.getEmail() + " has already been used to make an account");
System.out.println("Email already exists");
return;
} else if ((code = sendVerificationEmail(u)) == null) {
sendMessage(PacketHeader.EMAIL_NOT_VALID, "There was an error sending the email to "
+ u.getEmail() + ". Please make sure the email is correct");
System.out.println("email failed sending");
return;
}
sendMessage(PacketHeader.WAIT_FOR_CODE, "Type in code in email");
}
/**
* Sends an email to the user to verify that it is correct
*
* @param u The user to send the email to
* @return null - the email failed sending <br>
* random sting - the email successfully sent using this verification
* code
*/
private String sendVerificationEmail(User u) {
String code = RandomString.getAlphaNumericString(10);
if (Constants.getSendEmail().sendEmail(u, code)) {
return code;
}
return null;
}
/**
* Sends a packet to only the client
*
* @param packetHeader for the client to tell how to read in the message
* @param msg the message for the client
*/
private void sendMessage(PacketHeader packetHeader, Object msg) throws IOException {
System.out.println("Send to client: " + packetHeader);
Packet message = new Packet(packetHeader, msg);
//ERROR OCCURS HERE
output.writeObject(message);
output.flush();
}
private void closeConnections() {
if (user != null){
users.remove(user);
}
try {
sendToAll(new Packet(PacketHeader.MESSAGE, new Message(user.toString() + " has left the chat", new User("SERVER", null))));
} catch (IOException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
}
if (output != null){
writers.remove(output);
}
if (is != null) {
try {
is.close();
} catch (IOException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
if (os != null){
try {
os.close();
} catch (IOException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
if (input != null) {
try {
input.close();
} catch (IOException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
EDIT: here is the stacktrace
Nov 11, 2019 12:44:21 PM instachatfx.server.ServerMain$Handler run SEVERE: null java.io.EOFException at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2950) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1534) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427) at instachatfx.server.ServerMain$Handler.run(ServerMain.java:83)