Can't detach from screen session which runs java application
Hi there,
I am trying to run a long-running java command line application on a remote host through ssh and screen to be able to disconnect and reconnect later. The application provides the option to open a gui (in a JFrame) that shows current status and reclose it without actually exiting the application. However, if I do this, I cannot detach from the screen session anymore. More precisely, I can detach using ctrl-a-d, but when I then type exit to close the ssh session, it will say "Disconnected", but not give me the prompt of the local host back. Code:
user@remotehost:~$ screen I have been able to reproduce the issue with a stripped down java program. The source and additional info on OS etc... can be found below, I am running it as a jar on the remote host. Any ideas on what to do to fix this would be great. Code:
import java.awt.event.*; Setup: Localhost running Linux Aptosid Code:
~$ uname -r Code:
~$ java -version Code:
~$ ssh -V Code:
~$ uname -r Code:
~$ screen -version Code:
~$ java -version Code:
~$ ssh -V Many thanks in advance to everyone looking at this :-) |
I've run into this before but I just spawned the java app with nohup, my java app ran in the background and didn't have a GUI so a little different but it worked as a workaround. I didnt have any problems with the screen session not going away. If you spawn the java app with nohup it would allow you to keep it running while you see if you can diagnose the screen issues.
I would imagine it has to do with the way the GUI is starting and forking you off so that you aren't actually on the original terminal session. Thats just a thought, you should be able to check that with some ps commands and checking PPIDs if you have another terminal up at the same time. |
Hi Kustom. Thanks for your reply. Unfortunately nohup does not meet my needs as I have to be able to interact with the application while I am still logged in and I have to be able to reattach to it.
Quote:
In my real application I am starting the app on command line, and then only bring up the gui with a dedicated command that is read from stdin. If I never bring up the gui the detaching works smoothly. However the output of ps looks the same before and after bringing it the gui up. |
Just experimented around with this further and found I can strip it down a lot more. In fact the problem still occurs with the following java code:
Code:
import javax.swing.*; Note that non-swing objects to not cause problems. The following code lets me detach gracefully: Code:
public class Main |
I think I am getting closer to it. So when I ssh to the remote server without X11 forwarding I am getting the following exception when running the jar that instantiates a JPanel:
Code:
Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11GraphicsEnvironment I played around a bit with garbage collection etc. and it seems that destroying the JPanel instance is not sufficient to release this connection again. I have found this thread where they describe how dbus-launch is preventing ssh from exiting normally, and I could even reproduce this with e.g. thunar, but it does not seem to apply to my problem. I have compared the full list of processes (using ps -ef) before and after running the java code and there is no difference, except the jars processor scheduling value, i.e.: Code:
user 11066 10998 22 22:38 pts/4 00:00:01 java -jar jars/my_test_jar.jar Code:
user 11066 10998 30 22:38 pts/4 00:00:07 java -jar jars/my_test_jar.jar I have also tried to run the ssh session with the verbose switch. When I am trying to exit it is hanging here: Code:
user@remotehost:~$ exitdebug1: client_input_channel_req: channel 0 rtype exit-status reply 0 |
If the GUI component is using your local X server, you cannot sever the SSH connection without closing the X client GUI. It is probably the SSH server recognizing that the X tunnel is still active, and keeping the connection open until the X tunnel is unused. If you create a separate X connection that is not tunneled in the SSH connection, you will be able to close the SSH connection. It would require you to expose the X server to TCP connections, which is normally not the standard configuration.
--- rod. |
Quote:
|
On the X client host, run lsof, and see what TCP streams are open on ports 6000 to 6020 or so. These are very likely to be the ssh daemon listening for or maintaining an TCP connection that it uses to tunnel the X traffic. Coupled with the PID that the listing will provide, and the value of $DISPLAY in the shell session, you may be able to identify the process that is holding the TCP connection alive. From there you can make some choices about how to deal with it.
The value of $DISPLAY on a ssh-connected session with an X tunnel will be some smallish integer value. That value gets added to 6000 to form the TCP port number used by the ssh tunnel. X clients will use that port to try to connect to an X server on localhost. Finding the PID and nature of the X client that is (probably) holding open the connection may lead to a solution to your problem. --- rod. |
Quote:
So my $DISPLAY is 10, and when I launched the gui part of my java app I can see these two new line items in the output of LSOF, I guess that is what you were referring to. Code:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME So this question should really have been posted in a Java forum. Unless you disagree with the above I think I will post a new question in a java forum, possible linking to this thread here for background info, and report back if someone there can tell me how to do it. Again many thanks for the help so far. |
Hmmm. Something is not ringing true with that.
Quote:
--- rod. |
Quote:
I case you are interested you may find the thread I opened here: https://forums.oracle.com/forums/thr...00228&tstart=0 |
Quote:
No movement at all over there. That forum looks very quiet. Can't believe that nobody out there knows the answer to this question. You'd think it is a pretty basic one. But I am afraid I will have to work around it. Very unsatisfying... |
I finally solved it. I don't think it can be solved inside of java as long as one wants to keep using swing. (I believe swing does not support running in headless mode at all).
So it had to be on OS level. I found this nice tool called xpra. It allows to move an x application between different x displays. With that I can create a display, run my java application on it, and attach to that display when I want to look at the GUI. I can also detach from it again, all of that without killing the running process. For Debian Squeeze xpra does not seem to be in the standard repos, so I installed it using the instructions given on their website: http://xpra.org/debian.html |
All times are GMT -5. The time now is 02:07 AM. |