Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grabbing .jar application output stream to console after console was closed and new one opened on Oracle Solaris 11

On Oracle Solaris 11 console when ps -ef | grep java command is issued I can see running some java process PID, which was started on other console window and then it (console window) was closed (.jar application output then was visible). Is it some way to grab again that application output without restarting .jar file?

Application was started like this (as a root user):

java -jar SomeFile.jar &

Write output to file is not an option in this case.

like image 911
Ernestas Gruodis Avatar asked Nov 28 '25 13:11

Ernestas Gruodis


1 Answers

Yes, you can do that, but it involves some mad skills with gdb. Here is how to do that in Linux and I believe you can do the same in Solaris (since it has gdb and it has all needed system calls I'm gonna use further).

There are 3 file descriptors for standard streams:

  • stdin: 0
  • stdout: 1
  • stderr: 2

You are interested in stdout and stderr (both are console output), so you need file descriptors with numbers 1 and 2, just keep it in mind.

Now I'm gonna show you how to do what you ask for "okular" application (instead of your "java" application) for stderr stream.

  1. Run "okular" in terminal, like this:

    $ okular &
    

    and then close this terminal. This is just to simulate your situation.

  2. Open another terminal
  3. Look for "okular" process:

    $ ps aux | grep okular
    

    Output:

    joe      27599  2.2  0.9 515644 73944 ?        S    23:46   0:00 okular
    

    So "okular" PID is 27599.

  4. Look for open file descriptors of "okular" process:

    $ ls -l /proc/27599/fd
    

    Output:

    lrwx------ 1 joe joe 64 Feb 18 23:46 0 -> /dev/pts/0 (deleted)
    lrwx------ 1 joe joe 64 Feb 18 23:46 1 -> /dev/pts/0 (deleted)
    lrwx------ 1 joe joe 64 Feb 18 23:46 2 -> /dev/pts/0 (deleted)
    

    You see that all 3 streams are deleted.

  5. Now let's attach to our process with gdb:

    $ gdb -p 27599 /usr/bin/okular
    

    Inside of gdb perform next operations:

    (gdb) p close(2)
    (gdb) p creat("/tmp/okular_2", 0600)
    (gdb) detach
    (gdb) quit
    

    Here we invoked 2 system calls:

    • close(), to close file for stderr stream of our process
    • creat(), to create new file for stderr stream of our process

    p is gdb command, it prints (in our case) system calls return values.

  6. Now all new stderr output of our process will be appended to text file /tmp/okular_2. We can read it constantly this way:

    $ tail -f /tmp/okular_2
    

Conclusion

Ok, that's it, we revived stderr stream. You can do the same for stdout stream, the only difference is that you need to call "close(1)" instead of "close(2)" in gdb. Also, in your case be sure to replace all "okular" words with your "java" word.

The most of answer was inspired by this article.

If you need to revive stdin stream, you can attach it to pipe (FIFO) file, see details here.

like image 117
Sam Protsenko Avatar answered Dec 01 '25 23:12

Sam Protsenko