/Users/lyon/j4p/src/javagroup/misc/ProcessService.java
|
1 package javagroup.misc;
2
3 import javagroup.disposer.SocketDisposer;
4 import javagroup.process.JProcess;
5 import javagroup.process.ProcessManager;
6 import javagroup.process.ProcessManagerHolder;
7 import javagroup.util.NullInputStream;
8 import javagroup.util.Resource;
9 import javagroup.util.StandardIO;
10
11 import java.io.*;
12 import java.net.ServerSocket;
13 import java.net.Socket;
14
15 /**
16 * A service to listen on a socket and launch processes from client
17 * requests. Written as a basic example use of the multiprocess api, this
18 * code has been kept simple. A couple of features omitted are a
19 * trusted-host list, and thread-per-client communication to allow
20 * asynchronous requests.
21 *
22 * @author Luke Gorrie
23 * @version $Revision: 1.1 $
24 */
25 public class ProcessService implements Runnable {
26
27 /**
28 * Default port to listen on. *
29 */
30 public static final int DEFAULT_PORT = 7080;
31
32 /**
33 * ServerSocket to take connections from. *
34 */
35 protected ServerSocket _serverSocket;
36
37 public ProcessService() throws IOException {
38 this(DEFAULT_PORT);
39 }
40
41 public ProcessService(int port) throws IOException {
42 // bind a ServerSocket to take connections on
43 // raises IOException
44 _serverSocket = new ServerSocket(port);
45
46 new Thread(this).start();
47 }
48
49 /**
50 * Drives a thread to serve clients by creating processes. *
51 */
52 public void run() {
53 try {
54 // loop until thread is explicitly killed
55 while (true) {
56
57 // socket connection
58 Socket client_sock = null;
59
60 // PrintStream for writing to socket
61 PrintStream output = null;
62
63 try {
64 // accept a connection from a client
65 // raises IOException
66 client_sock = _serverSocket.accept();
67
68 // streams for process standard io
69 PrintStream out, err;
70 InputStream in;
71
72 // standard out and err are redirected to the socket
73 // raises IOException
74 out =
75 err =
76 output =
77 new PrintStream(client_sock.getOutputStream());
78
79 // use an empty stream for standard in
80 in = new NullInputStream();
81
82 // create standard-io set for process
83 StandardIO stdio = new StandardIO(out, in, err);
84
85 // create a stream to read command from
86 // raises IOException
87 DataInputStream input = new DataInputStream(
88 client_sock.getInputStream());
89
90 // read the command from the client
91 // raises IOException
92 BufferedReader br = new BufferedReader(
93 new InputStreamReader(input));
94 String command =
95 br.readLine();
96
97 // get a ProcessManager to launch the process
98 ProcessManager process_manager = ProcessManagerHolder.getProcessManager();
99
100 // create process
101 // raises ProcessCreationException
102 JProcess process = process_manager.createProcessFromString(
103 command);
104
105 // set standard io streams for process
106 process_manager.setStandardIOForProcess(process,
107 stdio);
108
109 // create Resource to bind the socket to the process
110 Resource socket_resource = new Resource(
111 new SocketDisposer(client_sock));
112
113 // register the resource to the process so that it is disposed
114 // when the process dies
115 process.registerResource(socket_resource);
116
117 // launch process
118 process.launch();
119 } catch (Exception e) {
120 try {
121 output.println(e);
122 client_sock.close();
123 } catch (Exception ioe) {
124 }
125 }
126 }
127 } catch (ExceptionInInitializerError e) {
128 e.getException().printStackTrace();
129 }
130 }
131
132 /**
133 * Closes the ServerSocket which was bound to listen for client
134 * requests.
135 */
136 public void finalize() {
137 try {
138 _serverSocket.close();
139 } catch (IOException e) {
140 }
141 }
142
143 /**
144 * Starts a ProcessService on the default port.
145 *
146 * @param args Ignored.
147 */
148 public static void main(String[] args) throws Exception {
149 new ProcessService();
150 }
151
152 }
153
154
155