Issue
This thread I have written has three try catches. The first is a try with resources to set up an ObjectOutputStream. The second recieves information from another on whether authentication has succeeded or failed. On success it should establish a map utilised in communication and on failure the thread is returned from. Likewise if an Interrupt or IOException occurs in this phase, the thread is returned from. Only in the eventuality of successful authentication as far as I can see should the second try catch be reached. This second block is responsible for handling packets it receives util the session ends either through interrupt or a packet requesting it. My problem is that on ending a session I am required to replace the aforementioned ConcurrenHashMap record pertaining to this thread with an empty Optional. this should occur in both previously outlined shutdown mechanisms. However the line responsible for this in the InterruptedException catch block says the map may not have been initialised despite the fact that it should be impossible to reach that block without its initialisation.
public void run(){
boolean quit = false;
Packet packet;
int cid, nid;
ConcurrentMap<Integer, Optional<BlockingQueue<Packet>>> channelMap;
try (ObjectOutputStream output = new ObjectOutputStream(new
BufferedOutputStream(sslSocket.getOutputStream()))) {
try {
packet = channel.take();
if (packet.getType() == AUTH_SUCCESS) {
cid = ((AuthSuccessPacket) packet).getCid();
nid = ((AuthSuccessPacket) packet).getNid();
channelMap = networkMap.get(nid);
channelMap.replace(cid, Optional.of(channel));
output.writeObject(packet);
} else {
output.writeObject(packet);
return;
}
}catch (IOException | InterruptedException e){
return;
}
while (!quit && !interrupted()) {
try {
packet = channel.take();
switch (packet.getType()) {
case ACK:
case MESSAGE:
case REQUEST_USER:
case RELAY_SHUTDOWN:
output.writeObject(packet);
break;
case END_SESSION:
if (packet.getSource() == cid) {
output.writeObject(packet);
channelMap.replace(cid, Optional.empty());
quit = true;
}
break;
}
}catch (IOException e){}
}
}catch (InterruptedException e){
channelMap.replace(cid, Optional.empty());
} catch (IOException e){}
}
What am I missing? Thanks.
Solution
I am not sure what the cause was but I moved the Interrupt to a separate catch of the second inner block and it no longer raised the exception.
Answered By - nrmad
Answer Checked By - Katrina (JavaFixing Volunteer)