1 23 package com.sun.enterprise.diagnostics.collect; 24 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.util.logging.Logger ; 28 import java.util.logging.Level ; 29 30 import com.sun.enterprise.util.i18n.StringManager; 31 32 import com.sun.logging.LogDomains; 33 34 35 40 public class ProcessExecutor { 41 42 static final Logger logger = 43 Logger.getLogger(LogDomains.ADMIN_LOGGER); 44 45 private String [] command; 46 47 private long timeout; 48 49 private ProcessRunner runner = null; 50 51 60 public ProcessExecutor(String [] cmd, long timeout) { 61 if (cmd == null || cmd.length == 0) { 62 throw new IllegalArgumentException ( 63 "process.null_or_empty_command"); 64 } 65 if (timeout < 0) { 66 throw new IllegalArgumentException ( 67 "process.invalid_timeout_value " + new Long (timeout)); 68 } 69 this.command = cmd; 70 this.timeout= timeout; 71 } 72 73 76 public String getCommandString() { 77 String cmdString = null; 78 if (runner != null) { 79 cmdString = runner.getCommandString(); 80 } 81 if (cmdString == null) { 82 StringBuffer buf = new StringBuffer (); 83 for (int i = 0; i < command.length; i++) { 84 buf.append(command[i] + " "); 85 } 86 cmdString = buf.toString(); 87 } 88 return cmdString; 89 } 90 91 94 public long getTimeout() { 95 return timeout; 96 } 97 98 104 public void setTimeout(long timeout) { 105 if (timeout >= 0) { 106 this.timeout = timeout; 107 } else { 108 throw new IllegalArgumentException ( 109 "process.invalid_timeout_value " + new Long (timeout)); 110 } 111 } 112 113 119 public String execute() throws ProcessExecutorException { 120 if (runner != null) { 121 throw new IllegalStateException ( 122 "process.already_executed"); 123 } 124 runner = new ProcessRunner(command, timeout); 125 Thread runnerThread = new Thread (runner); 126 runnerThread.start(); 127 try { 128 runnerThread.join(timeout); 129 } catch (InterruptedException ie) { 130 logger.log(Level.FINEST, "process.waiter_interrupted", 131 getCommandString()); 132 } 133 if (runnerThread.isAlive()) { 134 if (!runner.completed) { 135 logger.log(Level.FINEST, "process.interrupting", 136 new Object [] {new Long (timeout), getCommandString()}); 137 runnerThread.interrupt(); 138 try { 139 runnerThread.join(500); 141 } catch (InterruptedException ie) { 142 } 145 if (!runner.completed && !runner.interrupted) { 146 runner.interrupted = true; 148 } 149 } 150 } 151 if (runner.interrupted || runner.exception != null) { 152 if (runner.exception == null) { 153 runner.makeTimeoutException(); 156 } 157 throw runner.exception; 158 } 159 return runner.stdout.toString(); 160 } 161 162 166 public boolean isCompleted() { 167 boolean completed = false; 168 if (runner != null) { 169 completed = runner.completed; 170 } 171 return completed; 172 } 173 174 179 public boolean isInterrupted() { 180 boolean interrupted = false; 181 if (runner != null) { 182 interrupted = runner.interrupted; 183 } 184 return interrupted; 185 } 186 187 190 public String getStdout() { 191 String stdout = null; 192 if (runner != null) { 193 stdout = runner.stdout.toString(); 194 } 195 return stdout; 196 } 197 198 201 public String getStderr() { 202 String stderr = null; 203 if (runner != null) { 204 stderr = runner.stderr.toString(); 205 } 206 return stderr; 207 } 208 209 214 public int getExitCode() { 215 int exitCode = 0; 216 if (runner != null && runner.completed) { 217 exitCode = runner.exitCode; 218 } else { 219 throw new IllegalStateException ( 220 "process.not_yet_executed"); 221 } 222 return exitCode; 223 } 224 225 228 public String executeAgain() throws ProcessExecutorException { 229 runner = null; 230 return execute(); 231 } 232 } 233 234 238 class ProcessRunner implements Runnable { 239 240 static final Logger logger = ProcessExecutor.logger; 241 long timeout; 242 String [] cmd; 243 StringBuffer stdout = new StringBuffer (); 244 StringBuffer stderr = new StringBuffer (); 245 int exitCode; 246 boolean completed = false; 247 boolean interrupted = false; 248 ProcessExecutorException exception; 249 private String cmdString = null; 250 251 252 256 ProcessRunner(String [] cmd, long timeout) { 257 this.cmd = cmd; 258 this.timeout = timeout; 259 } 260 261 264 public void run() { 265 Process process = null; 266 InputStream is = null; 267 InputStream es = null; 268 try { 269 try { 270 process = Runtime.getRuntime().exec(cmd); 271 } catch (IOException ioe) { 272 logger.log(Level.FINE, "process.creation_failed", ioe); 273 makeOtherException(ioe); 274 return; 275 } 276 if (checkInterrupted()) { 277 return; 278 } 279 is = process.getInputStream(); 280 es = process.getErrorStream(); 281 readFromStream(es, stderr); 282 if (checkInterrupted()) { 283 return; 284 } 285 readFromStream(is, stdout); 286 if (checkInterrupted()) { 287 return; 288 } 289 try { 290 is.close(); 291 es.close(); 292 is = null; 293 es = null; 294 } catch (IOException ioe) { 295 logger.log(Level.FINEST, "process.stream_close_error", ioe); 296 } 297 exitCode = process.waitFor(); 298 if (exitCode != 0) { 299 makeAbnormalTerminationException(); 300 } 301 process.destroy(); 302 process = null; 303 completed = true; 304 } catch (InterruptedException ie) { 305 logger.log(Level.FINEST, "process.interrupted"); 306 interrupted = true; 307 makeTimeoutException(); 308 } catch (Exception e) { 309 logger.log(Level.FINEST, "process.execution_failed", e); 310 makeOtherException(e); 311 } finally { 312 try { 313 if (is != null) { 314 is.close(); 315 } 316 if (es != null) { 317 es.close(); 318 } 319 if (process != null) { 320 process.destroy(); 321 } 322 } catch (Throwable t) { 323 } 325 } 326 } 327 328 331 void readFromStream(InputStream stream, StringBuffer buffer) { 332 byte[] bytes = new byte[1024]; 333 try { 334 int count = 0; 335 while ((count = stream.read(bytes)) != -1) { 336 buffer.append(new String (bytes, 0 , count)); 337 if (checkInterrupted()) { 338 return; 339 } 340 } 341 } catch (IOException ioe) { 342 logger.log(Level.FINEST, "process.stream_read_error", ioe); 343 } 344 } 345 346 350 private boolean checkInterrupted() { 351 if (Thread.currentThread().isInterrupted()) { 352 interrupted = true; 353 makeTimeoutException(); 354 } 355 return interrupted; 356 } 357 358 361 void makeTimeoutException() { 362 String outs = stderr.toString() + "\n" + stdout.toString(); 363 exception = new ProcessExecutorException("process.timeout", 364 "Process timed out.\nTimeout was {2} msecs\n" 365 + "Attempted command: {0}\nOutput from command: {1}", 366 new Object [] { getCommandString(), outs, new Long (timeout) }); 367 } 368 369 372 void makeAbnormalTerminationException() { 373 String outs = stderr.toString() + "\n" + stdout.toString(); 374 exception = new ProcessExecutorException("process.abnormal_termination", 375 "Abnormal process termination -- process returned: {0}\n" 376 + "Attempted command: {1}\nOutput from command: {2}", 377 new Object [] { new Integer (exitCode), getCommandString(), 378 outs} ); 379 } 380 381 384 void makeOtherException(Throwable t) { 385 String outs = stderr.toString() + "\n" + stdout.toString(); 386 exception = new ProcessExecutorException("process.unknown_exception", 387 "Abnormal process termination -- process threw an Exception.\n" 388 + "Attempted command: {0}\nOutput from command: {1}", 389 new Object [] { getCommandString(), outs}, t ); 390 } 391 392 395 String getCommandString() { 396 if (cmdString == null) { 397 StringBuffer buf = new StringBuffer (); 398 for (int i = 0; i < cmd.length; i++) { 399 buf.append(cmd[i] + " "); 400 } 401 cmdString = buf.toString(); 402 } 403 return cmdString; 404 } 405 } 406 | Popular Tags |