KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > SingleThreadStdoutStderr


1 import java.io.IOException JavaDoc;
2 import java.io.InputStream JavaDoc;
3
4 import ch.ethz.ssh2.ChannelCondition;
5 import ch.ethz.ssh2.Connection;
6 import ch.ethz.ssh2.Session;
7
8 public class SingleThreadStdoutStderr
9 {
10     public static void main(String JavaDoc[] args)
11     {
12         String JavaDoc hostname = "127.0.0.1";
13         String JavaDoc username = "joe";
14         String JavaDoc password = "joespass";
15
16         try
17         {
18             /* Create a connection instance */
19
20             Connection conn = new Connection(hostname);
21
22             /* Now connect */
23
24             conn.connect();
25
26             /* Authenticate */
27
28             boolean isAuthenticated = conn.authenticateWithPassword(username, password);
29
30             if (isAuthenticated == false)
31                 throw new IOException JavaDoc("Authentication failed.");
32
33             /* Create a session */
34
35             Session sess = conn.openSession();
36
37             sess.execCommand("echo \"Huge amounts of text on STDOUT\"; echo \"Huge amounts of text on STDERR\" >&2");
38
39             /*
40              * Advanced:
41              * The following is a demo on how one can read from stdout and
42              * stderr without having to use two parallel worker threads (i.e.,
43              * we don't use the Streamgobblers here) and at the same time not
44              * risking a deadlock (due to a filled SSH2 channel window, caused
45              * by the stream which you are currently NOT reading from =).
46              */

47
48             /* Don't wrap these streams and don't let other threads work on
49              * these streams while you work with Session.waitForCondition()!!!
50              */

51
52             InputStream JavaDoc stdout = sess.getStdout();
53             InputStream JavaDoc stderr = sess.getStderr();
54
55             byte[] buffer = new byte[8192];
56
57             while (true)
58             {
59                 if ((stdout.available() == 0) && (stderr.available() == 0))
60                 {
61                     /* Even though currently there is no data available, it may be that new data arrives
62                      * and the session's underlying channel is closed before we call waitForCondition().
63                      * This means that EOF and STDOUT_DATA (or STDERR_DATA, or both) may
64                      * be set together.
65                      */

66
67                     int conditions = sess.waitForCondition(ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA
68                             | ChannelCondition.EOF, 2000);
69
70                     /* Wait no longer than 2 seconds (= 2000 milliseconds) */
71
72                     if ((conditions & ChannelCondition.TIMEOUT) != 0)
73                     {
74                         /* A timeout occured. */
75                         throw new IOException JavaDoc("Timeout while waiting for data from peer.");
76                     }
77
78                     /* Here we do not need to check separately for CLOSED, since CLOSED implies EOF */
79
80                     if ((conditions & ChannelCondition.EOF) != 0)
81                     {
82                         /* The remote side won't send us further data... */
83
84                         if ((conditions & (ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA)) == 0)
85                         {
86                             /* ... and we have consumed all data in the local arrival window. */
87                             break;
88                         }
89                     }
90
91                     /* OK, either STDOUT_DATA or STDERR_DATA (or both) is set. */
92
93                     // You can be paranoid and check that the library is not going nuts:
94
// if ((conditions & (ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA)) == 0)
95
// throw new IllegalStateException("Unexpected condition result (" + conditions + ")");
96
}
97
98                 /* If you below replace "while" with "if", then the way the output appears on the local
99                  * stdout and stder streams is more "balanced". Addtionally reducing the buffer size
100                  * will also improve the interleaving, but performance will slightly suffer.
101                  * OKOK, that all matters only if you get HUGE amounts of stdout and stderr data =)
102                  */

103
104                 while (stdout.available() > 0)
105                 {
106                     int len = stdout.read(buffer);
107                     if (len > 0) // this check is somewhat paranoid
108
System.out.write(buffer, 0, len);
109                 }
110
111                 while (stderr.available() > 0)
112                 {
113                     int len = stderr.read(buffer);
114                     if (len > 0) // this check is somewhat paranoid
115
System.err.write(buffer, 0, len);
116                 }
117             }
118
119             /* Close this session */
120
121             sess.close();
122
123             /* Close the connection */
124
125             conn.close();
126
127         }
128         catch (IOException JavaDoc e)
129         {
130             e.printStackTrace(System.err);
131             System.exit(2);
132         }
133     }
134 }
135
Popular Tags