These two code paths need to behave very differently. Dispose of ImageJ programmatically via the ImageJ2-based code path of #dispose() which in turn disposes the LegacyService and hence ImageJ 1.x.Shut down ImageJ through the UI via the ImageJ 1.x-based code path of ij.ImageJ#quit().There were other considerations too, of course. We fixed this discrepancy in the ImageJ legacy layer by always setting exitWhenQuitting to true as well. So even after we updated ImageJ2’s quitting routine to lean on ImageJ 1.x as much as possible (which seemed to fix the problem in many of our tests), it was still not always enough since System.exit(0) was never ultimately called. By default, ImageJ 1.x does not call System.exit(0) when quitting, but whenever it is launched via its main method, it does. But suffice to say that ij.ImageJ.main performs many actions which the ImageJ2 startup routine also needs to perform (but not in exactly the same way), such as handling command line arguments, most of which we covered-except for a call setting the exitWhenQuitting flag to true. There are several reasons for this from an architectural and technical standpoint, which are outside the scope of this blog post. The second class of problem was introduced because ImageJ2 does not launch ImageJ via the ij.ImageJ.main method. With a minor update to the Script Editor, its windows now still prompt to save changes when quitting (whoo hoo!), but without the fragility of the original approach. The approach proved too fragile and prone to deadlocks, so we ended up opting for a different approach instead. But it turns out that Java’s standard paradigm of allowing windows to cancel their own closing conflates the ideas of confirming the close (e.g., with the user) with the process of actually doing the close/dispose on the window afterward. We then dispatched a windowClosing event to each remaining window to give them a chance to opt out of being closed. To address the problem, we added a callback hook to ImageJ 1.x on the WindowManager.closeAllWindows() method, so that we could inject additional behavior. The behavior of ImageJ 1.x with other types of “non-sanctioned” windows (i.e., all Window instances other than ImageWindow, TextWindow or non- Editor PlugInFrame) is to dispose them immediately without warning just prior to shutdown. It was previously the case that if you quit ImageJ while the Script Editor had tabs with unsaved changes, those changes would be discarded with no chance to save first. This class of bug was introduced because we tried to improve upon ImageJ 1.x’s behavior relating to the closing of windows and dialogs. ImageJ completes its shutdown routine and all windows disappear, but the Java process continues running in the background because System.exit(0) is never called. The main window refuses to disappear, and the program becomes largely nonfunctional from that point forward and must be force closed. There were actually two different classes of misbehavior: (Actually, versions of this bug existed before bug #805 was reported, but that bug is where we have been tracking the issue most recently.)Īs of this writing, we have just released ImageJ 2.0.0-rc-9 which we believe finally solves this issue after six different attempts to fix it. Of all the issues reported, one has stood out as the most tenacious and difficult to solve: Fiji bug #805, “Fiji not closing”, colloquially known as the “Fiji won’t quit!” problem. For those who have reported bugs: thank you! Since releasing ImageJ2 into the wild, there has been a tremendous amount of user feedback.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |