If the host of a session leaves and thus throws all participants out, the following exception might occur if AbstractSessionListener.sessionEnded() is executed before AbstractSharedProjectListener.userLeft() in the EditorManager (race condition). In this case the SharedProject is already null when it is used in userLeft().
java.lang.NullPointerException
at de.fu_berlin.inf.dpp.editor.EditorManager$2.userLeft(EditorManager.java:436)
at de.fu_berlin.inf.dpp.project.internal.SharedProject.removeUser(SharedProject.java:244)
at de.fu_berlin.inf.dpp.net.business.LeaveHandler.leaveReceived(LeaveHandler.java:49)
at de.fu_berlin.inf.dpp.net.internal.extensions.LeaveExtension.processMessage(LeaveExtension.java:33)
at de.fu_berlin.inf.dpp.net.internal.extensions.SarosDefaultPacketExtension.processPacket(SarosDefaultPacketExtension.java:32)
at de.fu_berlin.inf.dpp.net.internal.XMPPChatReceiver.processPacket(XMPPChatReceiver.java:68)
at de.fu_berlin.inf.dpp.net.internal.XMPPChatTransmitter$XMPPChatTransmitterPacketListener$1.run(XMPPChatTransmitter.java:151)
at de.fu_berlin.inf.dpp.util.Util$6.run(Util.java:357)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
The suggested solution is to make Leave an activity and not a extension, because it needs to be carefully synchronized.
The given NPE was fixed in r.1258.
It is currently unclear which activities will be received, send or executed when a user leaves the session. This should be handled more gracefully (e.g disable receiving and execution of activities before sending the leave message). Furthermore the host has to handle the leave signal different when sending it to the other session users to ensure that all activities that were received from that user are executed on the remote side of the other users before they are notified that the user left the session.