/* * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the "License"). You may not use this file except * in compliance with the License. * * You can obtain a copy of the license at * https://open-esb.dev.java.net/public/CDDLv1.0.html. * See the License for the specific language governing * permissions and limitations under the License. * * When distributing Covered Code, include this CDDL * HEADER in each file and include the License file at * https://open-esb.dev.java.net/public/CDDLv1.0.html. * If applicable add the following below this CDDL HEADER, * with the fields enclosed by brackets "[]" replaced with * your own identifying information: Portions Copyright * [year] [name of copyright owner] */ /* * @(#)ProcessExecutor.java - ver 1.1 - 01/04/2006 * * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. */ package test.jbi; import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.OutputStream; /** * *This class is used to execute external commands */ /** * This is the inner class that consumes the error and output stream */ class StreamConsumer extends Thread { /** * The inputstream from the process */ InputStream is; /** * The string in which the results will be stored */ StringBuffer resultStore; /** * The boolean that denotes if this is installation * this is true if this is installation */ StreamConsumer ( InputStream is, StringBuffer resultStore) { this.is = is; this.resultStore = resultStore; } /** * The method that returns the stored result. i.e output * from the executed process */ public StringBuffer getResult() { return resultStore; } /** * the thread execution method. This method consumes the input from the * given stream and write it in the given resultStore. If no resultStore is given * then it is written into the debug file. Installer uses resultStore for commands * where the output has to be analysed and is predictably small. For example * output of asadmin start-domain. But for cases like invoking ant commands to * install files into the domain/or to install sample components, installer does not * supply result store and thus the output goes to the debug files. */ public void run() { try { InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line=null; while ( (line = br.readLine()) != null) { resultStore.append(line); } } catch (Exception ioe) { ioe.printStackTrace(); } } } /** * This class is used to timeout from the exec-ed process. * When the started process does not finish in the given time, this process * destroys the exec-ed process. */ class Watcher extends Thread { /** * member that holds the timeout value */ long timeout = 0; /** *member that holds reference to the exec-ed process */ Process process = null; /** * This method is used to set the timeout value * @param timeout value of timeout */ public void setTimeOut(long timeout){ this.timeout=timeout; } /** * This method is used to set the reference to the exec-ed process * @param process reference to the process */ public void setProcessReference(Process process){ this.process=process; } public void run() { try { sleep(timeout); } catch (InterruptedException ie) { } finally { process.destroy(); } } } /** * This class executes the given external command and returns the exitValue * output and error. */ public class ProcessExecutor { /** * This member holds the value for the default timeout in milliseconds */ private static long defaultTimeOut = 2*60*1000; /** * This method is used to execute a given external command * @return int the execute value * @param output after the command is executed * @param error after the command is executed */ public int execute( String cmd, StringBuffer output, StringBuffer error) { return execute(cmd, output, error, defaultTimeOut); } /** * This method is used to execute a given external command * @return int the execute value * @param output after the command is executed * the output is available in this StringBuffer * @param error after the command is executed * the error is available in this StringBuffer * This method is useful in situations where * we have to execute a command like * sh -c cd ~;ls. If the entire thing is passed as a single string * the way java makes a * string array out of it makes this command not work. So we make * the required array as we want. */ public int execute( String cmd, StringBuffer output, StringBuffer error, long timeout) { try { Runtime rt = Runtime.getRuntime(); //System.out.println(cmd); final Process proc = rt.exec(cmd); if (timeout > 0) { Watcher watcher = new Watcher(); watcher.setTimeOut(timeout); watcher.setProcessReference(proc); watcher.start(); }//timeout StreamConsumer errorConsumer = new StreamConsumer( proc.getErrorStream(), output); StreamConsumer outputConsumer = new StreamConsumer( proc.getInputStream(), error); errorConsumer.start(); outputConsumer.start(); int exitVal = proc.waitFor(); if (output != null) { output.insert(0, outputConsumer.getResult().toString()); } if (error != null) { error.insert(0, errorConsumer.getResult().toString()); } return exitVal; } catch(Exception e) { e.printStackTrace(); return -1; } } }