I made a java application that saves data to a .data file. I have a Window Listener that listens for the application to close in order to fire the code to save the data to the file. When pressing the dedicated quit button I have, or pressing the red "X" on the window, everything is fine. However, when the user opts for the command + q route things go sour. The application is quit, but the data is not saved. How do I correctly implement apple's handleQuit(Application Event e) method to fix this?
What you want in that case is a shutdown hook. A shutdown hook listens for the OS signal to close the app and is triggered when this signal is sent. A shutdown hook can run pretty much any code.
You can wire your built-in red "X" button to close the app (instead of saving the file), and the shutdown hook will catch the request and take care of saving the file.
The only caveat is that shutdown hooks are supposed to be made up of code that doesn't take very long to execute. So, the save of your file shouldn't take more than a second or two, and you shouldn't use confirmation dialog boxes that the user must acknowledge in a shutdown hook, because it can take an indefinite amount of time before the user recognizes the dialog.
The reason why shutdown hooks should be short lived is that when an application is requested to shutdown, the OS generally expects it to shutdown in a reasonable amount of time. If it doesn't, for example in Windows, the OS might display one of those, "Application isn't responding..." messages.
Finally, and you might run into this question later, you might wonder how to catch a "Force Quit" request from the Task Manager (or "Force Quit Applications" dialog on OS X). Well, you can't catch those, and you shouldn't try! While it is possible to disable things like listing your app in the Force Quit menu, this is a complete hack and should be avoided at all costs. If you're designing your app in a way that tries to circumvent options that should always be available to users and admins then that's a strong indication that your app is poorly designed, and/or a bad actor. Imagine if you installed an app that behaved in this way - wouldn't you think the programmer was being lazy or possibly malicious in trying to give their app un-killable qualities?
Also, force quitting is a forcible (ungraceful) shutdown that should only be used on applications when they are hung and won't quit normally. OSs need to have a force quit kind of option so that a user or admin has a way to kill a runaway or unresponsive app. If your users are force quitting your app they either misunderstand that force quitting isn't desirable, or there's something about the design of your app that makes force quitting more favorable than quitting your app normally. If this is the case (e.g. you hear from users that they force quit for one reason or another), it's usually an indication that portion of your app is poorly designed to match user's expectations.
Related
My project is basically a Communication client like lync which is developed in JAVA for front end (GUI) and uses platform specific native (C or C++) code for running services.
Now, on Linux, (Ubuntu 12.04), once the JAR application is invoked, it loads all the native code shared libraries and the UI thread starts executing. Any action done in the UI will throw an event to the native code which is in C. So currently i need to debug a crash in a C/C++ user library which is triggered when i do something in a UI drop down.
I am using GDB, to attach to the PID of the process , (sudo gdb -p ), all the symbols are loaded and i am able to set a breakpoint to a function say A() in the library.After continue command in GDB, i select the instance from UI Dropdown and breakpoint is hit at Function A(). At this moment, my ubuntu machine hangs and no keyboard interrupts are working. I am only able to move my mouse pointer but cannot click on anything.
However, to verify that kernel is not down, i can ping the machine and even SSH is possible. Once the same GDB is invoked by SSH the above problem is not encountered. May anyone please help me out here as to why UI or X11 process hangs during the above scenario.
PS: Yes there are lot of threads running, it might be a thread deadlock situation but it does not happen when GDB is invoked by SSH terminal.
Thanks and Regards,
Indra
why UI or X11 process hangs during the above scenario
As Mark Plotnick correctly pointed out, the X11 process does not hang. Rather, it grabs the keybard (all keyboard events are dispatched to it), and can not release that grab (it is stopped by GDB before it reaches the release point).
There are two common solutions:
ask the application to not do the keyboard grab (as Mark said), or
debug the application from a separate machine (this can even be done on single physical machine: just run the application inside a VM).
P.S. Why do application menues grab keyboard? Because hitting Esc usually dismisses the menu, and they want to see that Esc regardless of whether the application has input focus or not).
Hi I am writing an SWTBot test which launches a file from a hyperlink using Program.launch. From the bot test I need to check that the 3rd party application opened to display the file. The only thing that seems obvious to me is checking that focus was lost on the underlying workbench but all focus, enabled and visible assertions remain true. Does anyone have any assertion ideas here?
I would recommend to avoid letting the test spawn a process at all. You'll have to wait for the process, kill that process in tear down to leave a clean environment, etc.
If possible I'd rather mock the program launching code during tests and verify that it gets executed if the hyperlink was selected.
But if you really want to test that the 3rd party app was launched , I would rather check if a new process was created. There seems to be neither support in the JRE nor a library to list OS processes so that you probably have to resort to System.exec() ps or tasklist.exe, depending on the OS you are running on.
I have an applet packaged with a third part dll (from JTwain). My applet scans documents from the TWAIN compatible default printer. The applet fails on a paper jam and won't recover. The user navigates away from the page and the applet is destroyed. When returning to the page it fails again. Closing the browser (which kills java.exe process on the pc), and then returning to the page clears the problem and everything works.
I want to restart everything without requiring users to close down the browser. I've added a GUID query string to the URL's from which the applets resources are loaded - so I know nothing is being cached. I've checked in the windows task manager and there is no process created by the dll, it's all happening within the main java.exe process. I tried wrapping the scanning process in a thread so I could interrupt it in the stop or destroy methods (just in case the applets thread weren't stopped when the applet was destroyed), but that didn't work.
Any suggest would be greatly appreciated. Ideally I'd like some way to restart java when the applet unloads (but I doubt that's possible).
UPDATE
I've spent a couple of days trying to identify what causes the applet to fail. I still don't know :(
When the paper jam occurs something (not my code), is producing a couple of popups. The first alerts the user of the jam, and can be closed by clicking the OK button. The second says 'reading from device' and hangs. It cannot be close with the red, close window, icon in the top corner - I kill it from the task manager and windows asks to send a report regarding the 'non-responsive program'. I assume these popups are produced by the dll. And given that the second hangs, my assumption is that a thread started by the dll has hung while retaining a lock on some component of the TWAIN application. I get
com.asprise.util.jtwain.JTwainException: Failed to open the specified data source:
Source: TW-Brother MFC-9970CDW LAN Thrown
..when I try to access the scanner.
I'm at a bit of a loss as to how I can get more information. I'm testing my applet on a windows virtual pc (so as to use ie7), and don't have a method for step debugging in this environment. (And it's crashing on third party code for which I have no source anyway)
I see only two practical options here:
Use an API that handles paper jam without problems. Of course, that is easy to say (get robust API), harder to find.
Launch the app. free floating using Java Web Start. If it freezes up, the user can kill it and click the link for another instance in a new JVM. Or the applet might also call BasicService.showDocument(URLof.jnlp) if it can detect a problem with the DLL and is not itself frozen.
Of course, you should also report the bug to the ..Asprise(?) developers. The optimal solution would be to have the problem fixed at its source. Anything we do here is a 'workaround'.
Apple JVM on various OS X version have apparently been broken in that they do not generate the WindowClosing event when they should (for example if you close an app's main JFrame using by clicking on the close button).
(in the most recent Apple Java updates you can set a property forcing the event to be generated but this is not what I'm looking for)
My problem is simple: I'd like to display a "tip" when the user closes the app. However I cannot (due to the fact that no event is generated) detected that the user closed the window.
So I thought I could use a shutdown hook:
Runtime.getRuntime().addShutdownHook(...)
However apparently creating a JFrame from a shutdown hook seems problematic: it's like if the EDT was already gone once the shutdown hook is called.
I tried several things and nothing really seems to makes sense: like my "Tip" JFrame staying all gray (despite it working fine when called from anywhere but the shutdown hook) or the program exiting immediately. I tried using a latch and waiting on the latch from the shutdown hook but it's as if the EDT wasn't there anymore.
I'm currently seriously considering spawning a second Java app just to display the tooltip as a workaround but I think it's a bit overkill (but at least it would work).
Did anyone ever try to create a window from a shutdown hook and invoke things on the EDT and are there any gotchas to be aware of? (remember that I cannot reliably catch the window closing events on OS X due to known very-longstanding Apple VM bugs).
If the window is actually closing and the application is stopping then something is calling the JFrame.dispose() method. overwrite this, and add your code there.
otherwise you can add a daemon thread that listens to the closed method on the window listener, the daemon can add the tooltip and then dispose of the window. you can delay the dispose until the tooltip is done.
I've never heard of this bug, but things can only get better now that apple isnt releasing its own jdk's.
Well behaved windows programs need to allow users to save their work when they are shutting the PC down.
How can I make my app detect the shutdown event? Any solution should allow the user to abort the shutdown if user selects, say "Cancel".
The normal Swing window closing hook doesn't work, nor does adding a shutdown hook.
On testing, the methods of WindowListener (windowClosing,windowClosed, etc) do not get called.
The answer I have accepted requires the use of platform specific code (JNI to register for WM_QUERYENDSESSION ). Isn't this a bug on Swing?
See http://forums.sun.com/thread.jspa?threadID=481807&messageID=2246870
Write some JNI code to WM_QUERYENDSESSION message. You can get details for this from the MSDN documentation or by googling it.
If you don't want to write too much C++ code to do this I can recommend the JNA library click here. Which gives you some nice Java abstractions for C code.
how-do-i-get-my-java-application-to-shutdown-nicely-in-windows
That might be of help
The above seems to be the better answer.
I can't find any good information on detecting window shutdown events. I guess the best possible method would be to detect weather your application is trying to close, using a window closing event or the like then ask the question.
http://www.javalobby.org/java/forums/t17933
Look for signal handling in java. when Windows closes it will send a signal to the application asking it to terminate most likely a sigterm
see here for more about this (I am not the owner of the website)