1 23 package com.sun.ejb.codegen; 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 39 public class ProcessExecutor { 40 41 private static final StringManager localStrings = 42 StringManager.getManager(ProcessExecutor.class); 43 static final Logger logger = 44 Logger.getLogger(LogDomains.DPL_LOGGER); 45 46 private String [] command; 47 48 private long timeout; 49 50 private ProcessRunner runner = null; 51 52 61 public ProcessExecutor(String [] cmd, long timeout) { 62 if (cmd == null || cmd.length == 0) { 63 throw new IllegalArgumentException ( 64 localStrings.getString("process.null_or_empty_command")); 65 } 66 if (timeout <= 0) { 67 throw new IllegalArgumentException ( 68 localStrings.getString("process.invalid_timeout_value", 69 new Long (timeout))); 70 } 71 this.command = cmd; 72 this.timeout= timeout; 73 } 74 75 78 public String getCommandString() { 79 String cmdString = null; 80 if (runner != null) { 81 cmdString = runner.getCommandString(); 82 } 83 if (cmdString == null) { 84 StringBuffer buf = new StringBuffer (); 85 for (int i = 0; i < command.length; i++) { 86 buf.append(command[i] + " "); 87 } 88 cmdString = buf.toString(); 89 } 90 return cmdString; 91 } 92 93 96 public long getTimeout() { 97 return timeout; 98 } 99 100 106 public void setTimeout(long timeout) { 107 if (timeout >= 0) { 108 this.timeout = timeout; 109 } else { 110 throw new IllegalArgumentException ( 111 localStrings.getString("process.invalid_timeout_value", 112 new Long (timeout))); 113 } 114 } 115 116 122 public String execute() throws ProcessExecutorException { 123 if (runner != null) { 124 throw new IllegalStateException ( 125 localStrings.getString("process.already_executed")); 126 } 127 runner = new ProcessRunner(command, timeout); 128 Thread runnerThread = new Thread (runner); 129 runnerThread.start(); 130 try { 131 runnerThread.join(timeout); 132 } catch (InterruptedException ie) { 133 logger.log(Level.FINEST, "process.waiter_interrupted", 134 getCommandString()); 135 } 136 if (runnerThread.isAlive()) { 137 if (!runner.completed) { 138 logger.log(Level.FINEST, "process.interrupting", 139 new Object [] {new Long (timeout), getCommandString()}); 140 runnerThread.interrupt(); 141 try { 142 runnerThread.join(500); 144 } catch (InterruptedException ie) { 145 } 148 if (!runner.completed && !runner.interrupted) { 149 runner.interrupted = true; 151 } 152 } 153 } 154 if (runner.interrupted || runner.exception != null) { 155 if (runner.exception == null) { 156 runner.makeTimeoutException(); 159 } 160 throw runner.exception; 161 } 162 return runner.stdout.toString(); 163 } 164 165 169 public boolean isCompleted() { 170 boolean completed = false; 171 if (runner != null) { 172 completed = runner.completed; 173 } 174 return completed; 175 } 176 177 182 public boolean isInterrupted() { 183 boolean interrupted = false; 184 if (runner != null) { 185 interrupted = runner.interrupted; 186 } 187 return interrupted; 188 } 189 190 193 public String getStdout() { 194 String stdout = null; 195 if (runner != null) { 196 stdout = runner.stdout.toString(); 197 } 198 return stdout; 199 } 200 201 204 public String getStderr() { 205 String stderr = null; 206 if (runner != null) { 207 stderr = runner.stderr.toString(); 208 } 209 return stderr; 210 } 211 212 217 public int getExitCode() { 218 int exitCode = 0; 219 if (runner != null && runner.completed) { 220 exitCode = runner.exitCode; 221 } else { 222 throw new IllegalStateException ( 223 localStrings.getString("process.not_yet_executed")); 224 } 225 return exitCode; 226 } 227 228 231 public String executeAgain() throws ProcessExecutorException { 232 runner = null; 233 return execute(); 234 } 235 } 236 237 241 class ProcessRunner implements Runnable { 242 243 static final Logger logger = ProcessExecutor.logger; 244 long timeout; 245 String [] cmd; 246 StringBuffer stdout = new StringBuffer (); 247 StringBuffer stderr = new StringBuffer (); 248 int exitCode; 249 boolean completed = false; 250 boolean interrupted = false; 251 ProcessExecutorException exception; 252 private String cmdString = null; 253 254 255 259 ProcessRunner(String [] cmd, long timeout) { 260 this.cmd = cmd; 261 this.timeout = timeout; 262 } 263 264 267 public void run() { 268 Process process = null; 269 InputStream is = null; 270 InputStream es = null; 271 try { 272 try { 273 process = Runtime.getRuntime().exec(cmd); 274 } catch (IOException ioe) { 275 logger.log(Level.FINE, "process.creation_failed", ioe); 276 makeOtherException(ioe); 277 return; 278 } 279 if (checkInterrupted()) { 280 return; 281 } 282 is = process.getInputStream(); 283 es = process.getErrorStream(); 284 readFromStream(es, stderr); 285 if (checkInterrupted()) { 286 return; 287 } 288 readFromStream(is, stdout); 289 if (checkInterrupted()) { 290 return; 291 } 292 try { 293 is.close(); 294 es.close(); 295 is = null; 296 es = null; 297 } catch (IOException ioe) { 298 logger.log(Level.FINEST, "process.stream_close_error", ioe); 299 } 300 exitCode = process.waitFor(); 301 if (exitCode != 0) { 302 makeAbnormalTerminationException(); 303 } 304 process.destroy(); 305 process = null; 306 completed = true; 307 } catch (InterruptedException ie) { 308 logger.log(Level.FINEST, "process.interrupted"); 309 interrupted = true; 310 makeTimeoutException(); 311 } catch (Exception e) { 312 logger.log(Level.FINEST, "process.execution_failed", e); 313 makeOtherException(e); 314 } finally { 315 try { 316 if (is != null) { 317 is.close(); 318 } 319 if (es != null) { 320 es.close(); 321 } 322 if (process != null) { 323 process.destroy(); 324 } 325 } catch (Throwable t) { 326 } 328 } 329 } 330 331 334 void readFromStream(InputStream stream, StringBuffer buffer) { 335 byte[] bytes = new byte[1024]; 336 try { 337 int count = 0; 338 while ((count = stream.read(bytes)) != -1) { 339 buffer.append(new String (bytes, 0 , count)); 340 if (checkInterrupted()) { 341 return; 342 } 343 } 344 } catch (IOException ioe) { 345 logger.log(Level.FINEST, "process.stream_read_error", ioe); 346 } 347 } 348 349 353 private boolean checkInterrupted() { 354 if (Thread.currentThread().isInterrupted()) { 355 interrupted = true; 356 makeTimeoutException(); 357 } 358 return interrupted; 359 } 360 361 364 void makeTimeoutException() { 365 String outs = stderr.toString() + "\n" + stdout.toString(); 366 exception = new ProcessExecutorException("process.timeout", 367 "Process timed out.\nTimeout was {2} msecs\n" 368 + "Attempted command: {0}\nOutput from command: {1}", 369 new Object [] { getCommandString(), outs, new Long (timeout) }); 370 } 371 372 375 void makeAbnormalTerminationException() { 376 String outs = stderr.toString() + "\n" + stdout.toString(); 377 exception = new ProcessExecutorException("process.abnormal_termination", 378 "Abnormal process termination -- process returned: {0}\n" 379 + "Attempted command: {1}\nOutput from command: {2}", 380 new Object [] { new Integer (exitCode), getCommandString(), 381 outs} ); 382 } 383 384 387 void makeOtherException(Throwable t) { 388 String outs = stderr.toString() + "\n" + stdout.toString(); 389 exception = new ProcessExecutorException("process.unknown_exception", 390 "Abnormal process termination -- process threw an Exception.\n" 391 + "Attempted command: {0}\nOutput from command: {1}", 392 new Object [] { getCommandString(), outs}, t ); 393 } 394 395 398 String getCommandString() { 399 if (cmdString == null) { 400 StringBuffer buf = new StringBuffer (); 401 for (int i = 0; i < cmd.length; i++) { 402 buf.append(cmd[i] + " "); 403 } 404 cmdString = buf.toString(); 405 } 406 return cmdString; 407 } 408 } 409 | Popular Tags |