1 22 package org.jboss.varia.process; 23 24 import java.util.Properties ; 25 import java.util.Iterator ; 26 27 import java.io.File ; 28 import java.io.InputStream ; 29 import java.io.Reader ; 30 import java.io.IOException ; 31 import java.io.InputStreamReader ; 32 import java.io.BufferedReader ; 33 34 import org.apache.log4j.Level; 35 import org.apache.log4j.Logger; 36 37 import org.jboss.system.ServiceMBeanSupport; 38 39 import org.jboss.util.NullArgumentException; 40 41 49 public class ChildProcessService 50 extends ServiceMBeanSupport 51 implements ChildProcessServiceMBean 52 { 53 54 protected String commandLine; 55 56 57 protected Properties env; 58 59 60 protected File workingDir; 61 62 63 protected Process childProcess; 64 65 68 protected String loggerAdapterName = this.getClass().getName(); 69 70 74 protected ReaderLoggerAdapter inputAdapter; 75 76 80 protected ReaderLoggerAdapter errorAdapter; 81 82 85 public void setCommandLine(final String commandLine) 86 { 87 if (commandLine == null) 88 throw new NullArgumentException("commandLine"); 89 90 this.commandLine = commandLine; 91 } 92 93 96 public String getCommandLine() 97 { 98 return commandLine; 99 } 100 101 104 public void setEnvironment(final Properties env) 105 { 106 this.env = env; 107 } 108 109 112 public Properties getEnvironment() 113 { 114 return env; 115 } 116 117 120 public void setWorkingDirectory(final File dir) 121 { 122 if (dir != null) { 124 if (dir.exists()) { 125 if (!dir.isDirectory()) { 126 throw new IllegalArgumentException 127 ("Directory argument does not point to a directory: " + dir); 128 } 129 } 130 } 131 132 this.workingDir = dir; 133 } 134 135 138 public File getWorkingDirectory() 139 { 140 return workingDir; 141 } 142 143 146 public Integer getExitValue() 147 { 148 if (childProcess != null) { 149 return new Integer (childProcess.exitValue()); 150 } 151 152 return null; 153 } 154 155 158 public void setLoggerAdapterName(final String name) 159 { 160 this.loggerAdapterName = name; 161 } 162 163 166 public String getLoggerAdapterName() 167 { 168 return loggerAdapterName; 169 } 170 171 protected String [] makeEnvArray(final Properties props) 172 { 173 if (props == null) 174 return new String [0]; 175 176 String [] envArray = new String [props.keySet().size()]; 177 178 Iterator iter = props.keySet().iterator(); 179 int i = 0; 180 while (iter.hasNext()) { 181 String name = (String )iter.next(); 182 envArray[i++] = name + "=" + props.getProperty(name); 183 } 184 185 return envArray; 186 } 187 188 192 protected static class ReaderLoggerAdapter 193 implements Runnable 194 { 195 protected BufferedReader reader; 196 protected boolean shutdown; 197 protected Logger log; 198 protected Level level; 199 200 public ReaderLoggerAdapter(final Reader reader, final Logger log, final Level level) 201 { 202 if (reader instanceof BufferedReader ) { 203 this.reader = (BufferedReader )reader; 204 } 205 else { 206 this.reader = new BufferedReader (reader); 207 } 208 209 this.log = log; 210 this.level = level; 211 } 212 213 public ReaderLoggerAdapter(final InputStream input, final Logger log, final Level level) 214 { 215 this(new InputStreamReader (input), log, level); 216 } 217 218 public void shutdown() 219 { 220 shutdown = true; 221 } 222 223 public void run() 224 { 225 while (!shutdown) { 226 try { 227 String data = reader.readLine(); 228 if (data == null) { 229 try { 230 Thread.sleep(1000); 231 } 232 catch (InterruptedException ignore) {} 233 } 234 else { 235 log.log(level, data); 236 } 237 } 238 catch (IOException e) { 239 log.error("Failed to read data from reader", e); 240 } 241 } 242 } 243 } 244 245 246 250 protected void startService() throws Exception 251 { 252 Runtime rt = Runtime.getRuntime(); 253 254 childProcess = rt.exec(commandLine, makeEnvArray(env), workingDir); 255 log.info("Spawned child process: " + commandLine); 256 257 Logger logger = Logger.getLogger(loggerAdapterName); 259 260 InputStream input = childProcess.getInputStream(); 261 inputAdapter = new ReaderLoggerAdapter(input, logger, Level.INFO); 262 new Thread (inputAdapter).start(); 263 264 InputStream error = childProcess.getErrorStream(); 265 errorAdapter = new ReaderLoggerAdapter(error, logger, Level.ERROR); 266 new Thread (errorAdapter).start(); 267 } 268 269 protected void stopService() throws Exception 270 { 271 childProcess.destroy(); 272 273 log.debug("Child process destroyed; waiting for process to exit"); 274 childProcess.waitFor(); 275 276 log.info("Child exited with code: " + getExitValue()); 277 278 inputAdapter.shutdown(); 279 errorAdapter.shutdown(); 280 281 childProcess = null; 282 inputAdapter = null; 283 errorAdapter = null; 284 } 285 } 286 | Popular Tags |