I'm seeing a memory leak in a java swing application. It's leaking LightweightFocusRequest objects connected under a HeavyweightFocusRequest in the DefaultKeyboardFocusManager. The application runs in an undecorated, alwaysontop JFrame. (i.e. full-screen).
The application appears to have focus. Users can click on it, and interact (all via mouse as it's a kiosk w/o a keyboard). But each interaction that produces a focus request such as showing a dialog, etc, leaks the LightweightFocusRequest object.
I was able to determine this via a heap-dump and the Eclipse Memory Analyzer tool. As a workaround, if the application is switched out of fullscreen mode and the user clicks on another app, and back on our app, then the leaked memory is reclaimed as the outstanding focus request events are all cleared.
It's acting as if the java application missed a focus gained event.
I've seen this problem under Windows with jre version 1.6.0_35 (and _27). Not all users suffer the issue, so I don't know what other factors contribute. I also can't say for sure that it happens or doesn't happen under the latest 1.7 JRE, as the JRE versions used are beyond my control. The majority (90%+) are 1.6.0_20 to 1.6.0_39.
All attempts to reproduce the problem have failed.
My next strategy as a workaround is to add a check in the application on a timer to examine the focus request queue via reflection. If it looks like it's leaking (100+ outstanding items?) then create another window, give it focus, re-request focus and close the other temp window.
Has anyone seen a problem like this before or have a better workaround? My searching for something similar in the java bugdb and google wasn't fruitful.
Related
Recently, our Java application was a bit slower than usual, we just ignored it, because we use cloud DB which is a bit slow sometimes.
I used to navigate to other windows by pressing (alt+tab) in the windows machine. One day I found many JDialog boxes are opened. When we click it, nothing happens and it is also not shown. Again, when I press alt+tab, it is still here.
If I kill the application all the dialog boxes vanish. Since our codebase is huge with 5000+ Java classes, we don't know how to find this dialog box.
you can create a heap dump using jmap (jmap -dump:file=filename PID). after that you can see in the dump which of the JDialog remained in memory using the visual vm
How can I disable OS-level keyboard shortcuts (e.g. Alt-Tab, Ctrl-Alt-Left/Right, etc.) on a [Ubuntu] Linux machine? I'm developing a full-screen Java Swing app and don't want the user to be able to task switch away from the program arbitrarily. It's not enough to toggle the "always on top" flag; users mustn't be allowed to switch workspaces, migrate focus or any other such things. The machine must function normally before and after the application is executed. Google says that this will require JNI or JNA but I'm looking for a bit more hand-holding.
There's no point in trying to do this in your application because any of these changes are going to need to be handled by X11 and/or the window manager since those are what respond to the commands. Assuming that you have control of the platform, choose a window manager which supports a kiosk mode. Then use the window manager's settings to start your application and enter kiosk mode.
Options for window managers which can do this include KDE or twm-kiosk.
(And if you don't have control of the platform, you're not likely to be able to have your application intercept things like ctrl-alt-backspace anyway.)
Edit:
In response to a scaled-down version of the question in which he's willing to let things like ctl-alt-backspace go and just wants most of the keys including alt-tab or other similar application switching key combinations, the following should work:
You should be able to do this using XLib's XGrabKeyboard method through JNI. This Java/XLib JNI keypress capture tutorial should be a good starting point. However, it uses XGrabKey which just passively listens for keys and does not prevent other applications from receiving them. You'll instead want to use XGrabKeyboard which actively snags all of the normal keyboard events (which, if the premise of this StackOverflow question is correct, includes the task switching keys).
Note that as a side-effect, key capture in Swing will also probably stop working because your Swing windows are going to be separate from the window you create in C. As such, you will probably have to use your JNI interface to get key presses to your program when needed. (Although I would definitely advise testing it first before writing the code.) You might be able to avoid this if you can get the window using Java AWT Native Interface to get the window ID. (Note that Swing is built on top of AWT, so this will work for Swing.) However, I'm not sure how to do this. It looks like you might be able to navigate the window tree by getting the root window from the Display and going from there to find your Window, but it's all kind of weird. It would be nice if the AWT NI just told you the window ID, but it doesn't look like it does that.
As this warning Reminder: XGrabKeyboard is not a security interface notes, this doesn't make it impossible for other programs to see the keys, but it seems likely that window managers will not be using XQueryKeyMap so it is likely to prevent task switching.
I need to add a functionality in my application that would require me to know when the user changes window (it could be a browser window, my application's window or any other window).
Ideally, it should be possible for me to print the window's title when it gets focus. The problem I'm having finding a solution to this problem is that I only get links that tell me how to add a focus listener on windows I'm creating, which I already know how to do and doesn't help me in the slightest.
The solution should at least work on Windows 7.
The (major) problem you face is that Java filters system events so that you can only recieve events that are related to you. AFAIK this is all done at a native level, so there's no way to intercept or modify this filtering process.
The only solution is to create another "event loop" using JNI/JNA which will allow you to intercept the event messages being passed about the system and handle them the way you want to.
While slightly more complicated, it does open up a world of opportunities...
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'.
I have a rather strange question:
I have a Java application which uses "applications" (plugins) run in different threads.
Most of these plugins will be written by other people and I will have no control over the code. The application requires a permanent connection to the Internet as information is constantly transferred between the server and app. What I want to do is have a thread which runs in the backround checking to see if there is a Internet connection. If the connection drops I want the ENTIRE application (and all its threads) to pause, display a message and when reconnected resume. I want this dialog box to be displayed above all other dialog boxes (modal or not). I'm thinking of something like the Windows Vista User Account Control Alerts.
How can I do this?
To solve this at all reasonably, you need to use Java 6, as previous versions simply don't give you the granularity of modality you need.
Here are the modality options.
For this to work effectively, you would have to have each plugin honor a contract to not use Toolkit modality (the default behavior is that a modal dialog box locks everything up, to keep backwards compatibility). Application modality would seem to be a great fit for you, but I don't see that you can implement this in Java. This seems to be up to the JVM vendor, as far as I could find.