1 package org.objectweb.celtix.testutil.common; 2 3 import java.io.File ; 4 import java.io.FileNotFoundException ; 5 import java.io.FileOutputStream ; 6 import java.io.IOException ; 7 import java.io.InputStream ; 8 import java.io.PrintStream ; 9 import java.lang.reflect.Constructor ; 10 import java.net.URL ; 11 import java.net.URLClassLoader ; 12 import java.util.ArrayList ; 13 import java.util.List ; 14 import java.util.Map ; 15 import java.util.logging.Logger ; 16 17 public class ServerLauncher { 18 19 public static final int DEFAULT_TIMEOUT = 3 * 60 * 1000; 20 21 protected static final String SERVER_FAILED = 22 "server startup failed (not a log message)"; 23 24 private static final boolean DEFAULT_IN_PROCESS = false; 25 26 private static final Logger LOG = Logger.getLogger(ServerLauncher.class.getName()); 27 28 boolean serverPassed; 29 final String className; 30 31 32 private final boolean debug = false; 33 private boolean inProcess = DEFAULT_IN_PROCESS; 34 private AbstractTestServerBase inProcessServer; 35 36 private final String javaExe; 37 private Process process; 38 private boolean serverIsReady; 39 private boolean serverIsStopped; 40 private boolean serverLaunchFailed; 41 private Map <String , String > properties; 42 private String [] serverArgs; 43 44 private final Mutex mutex = new Mutex(); 45 46 public ServerLauncher(String theClassName) { 47 this(theClassName, DEFAULT_IN_PROCESS); 48 } 49 public ServerLauncher(String theClassName, boolean inprocess) { 50 inProcess = inprocess; 51 className = theClassName; 52 javaExe = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"; 53 } 54 public ServerLauncher(String theClassName, Map <String , String > p, String [] args) { 55 this(theClassName, p, args, false); 56 } 57 public ServerLauncher(String theClassName, Map <String , String > p, String [] args, boolean inprocess) { 58 className = theClassName; 59 properties = p; 60 serverArgs = args; 61 inProcess = inprocess; 62 javaExe = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"; 63 } 64 65 private boolean waitForServerToStop() { 66 synchronized (mutex) { 67 while (!serverIsStopped) { 68 try { 69 TimeoutCounter tc = new TimeoutCounter(DEFAULT_TIMEOUT); 70 mutex.wait(DEFAULT_TIMEOUT); 71 if (tc.isTimeoutExpired()) { 72 System.out.println("destroying server process"); 73 process.destroy(); 74 break; 75 } 76 } catch (InterruptedException ex) { 77 ex.printStackTrace(); 78 } 79 } 80 if (!inProcess) { 81 TimeoutCounter tc = new TimeoutCounter(DEFAULT_TIMEOUT); 83 while (!tc.isTimeoutExpired()) { 84 try { 85 process.exitValue(); 86 break; 87 } catch (IllegalThreadStateException ex) { 88 try { 90 Thread.sleep(1000); 91 } catch (InterruptedException ex1) { 92 } 94 } 95 } 96 if (tc.isTimeoutExpired()) { 97 process.destroy(); 98 } 99 } 100 } 101 return serverIsStopped; 102 } 103 104 public void signalStop() throws IOException { 105 if (process != null) { 106 process.getOutputStream().write('q'); 107 process.getOutputStream().write('\n'); 108 process.getOutputStream().flush(); 109 } 110 } 111 public boolean stopServer() throws IOException { 112 if (inProcess) { 113 try { 114 return inProcessServer.stopInProcess(); 115 } catch (Exception ex) { 116 ex.printStackTrace(); 117 throw new IOException (ex.getMessage()); 118 } 119 } else { 120 if (process != null) { 121 if (!serverIsStopped) { 122 try { 123 signalStop(); 124 } catch (IOException ex) { 125 } 127 } 128 waitForServerToStop(); 129 process.destroy(); 130 } 131 } 132 return serverPassed; 133 } 134 135 public boolean launchServer() throws IOException { 136 137 serverIsReady = false; 138 serverLaunchFailed = false; 139 140 if (inProcess) { 141 Class <?> cls; 142 try { 143 cls = Class.forName(className); 144 Class <? extends AbstractTestServerBase> svcls = 145 cls.asSubclass(AbstractTestServerBase.class); 146 if (null == serverArgs) { 147 inProcessServer = svcls.newInstance(); 148 } else { 149 Constructor ctor = svcls.getConstructor(serverArgs.getClass()); 150 inProcessServer = (AbstractTestServerBase)ctor.newInstance(new Object [] {serverArgs}); 151 } 152 inProcessServer.startInProcess(); 153 serverIsReady = true; 154 } catch (Exception ex) { 155 ex.printStackTrace(); 156 serverLaunchFailed = true; 157 } 158 } else { 159 List <String > cmd = getCommand(); 160 161 if (debug) { 162 System.err.print("CMD: "); 163 } 164 165 166 ProcessBuilder pb = new ProcessBuilder (cmd); 167 pb.redirectErrorStream(true); 168 process = pb.start(); 169 170 launchOutputMonitorThread(process.getInputStream(), System.out); 171 172 synchronized (mutex) { 173 do { 174 TimeoutCounter tc = new TimeoutCounter(DEFAULT_TIMEOUT); 175 try { 176 mutex.wait(DEFAULT_TIMEOUT); 177 if (tc.isTimeoutExpired()) { 178 break; 179 } 180 } catch (InterruptedException e) { 181 e.printStackTrace(); 182 } 183 } while (!serverIsReady && !serverLaunchFailed); 184 } 185 } 186 return serverIsReady; 187 } 188 189 public int waitForServer() { 190 int ret = -1; 191 try { 192 process.waitFor(); 193 ret = process.exitValue(); 194 } catch (InterruptedException e) { 195 e.printStackTrace(); 196 } 197 return ret; 198 } 199 200 private void launchOutputMonitorThread(final InputStream in, final PrintStream out) { 201 Thread t = new OutputMonitorThread(in, out); 202 t.start(); 203 } 204 private class OutputMonitorThread extends Thread { 205 InputStream in; 206 PrintStream out; 207 208 OutputMonitorThread(InputStream i, PrintStream o) { 209 in = i; 210 out = o; 211 } 212 213 public void run() { 214 try { 215 StringBuilder serverOutput = new StringBuilder (); 216 String outputDir = System.getProperty("server.output.dir", "target/surefire-reports/"); 217 FileOutputStream fos; 218 try { 219 fos = new FileOutputStream (outputDir + className + ".out"); 220 } catch (FileNotFoundException fex) { 221 outputDir = System.getProperty("basedir") + "/target/surefire-reports/"; 222 fos = new FileOutputStream (outputDir + className + ".out"); 223 } 224 PrintStream ps = new PrintStream (fos); 225 boolean running = true; 226 for (int ch = in.read(); ch != -1; ch = in.read()) { 227 serverOutput.append((char)ch); 228 if (debug) { 229 System.err.print((char)ch); 230 } 231 String s = serverOutput.toString(); 232 if (s.contains("server ready")) { 233 notifyServerIsReady(); 234 } else if (s.contains("server passed")) { 235 serverPassed = true; 236 } else if (s.contains("server stopped")) { 237 notifyServerIsStopped(); 238 running = false; 239 } else if (s.contains(SERVER_FAILED)) { 240 notifyServerFailed(); 241 running = false; 242 } 243 if (ch == '\n' || !running) { 244 synchronized (out) { 245 ps.print(serverOutput.toString()); 246 serverOutput = new StringBuilder (); 247 ps.flush(); 248 } 249 } 250 } 251 252 } catch (IOException ex) { 253 if (!ex.getMessage().contains("Stream closed")) { 254 ex.printStackTrace(); 255 } 256 } 257 } 258 } 259 260 void notifyServerIsReady() { 261 synchronized (mutex) { 262 serverIsReady = true; 263 mutex.notifyAll(); 264 } 265 } 266 267 void notifyServerIsStopped() { 268 synchronized (mutex) { 269 LOG.info("notify server stopped"); 270 serverIsStopped = true; 271 mutex.notifyAll(); 272 } 273 } 274 275 void notifyServerFailed() { 276 synchronized (mutex) { 277 serverIsStopped = true; 278 mutex.notifyAll(); 279 } 280 } 281 282 private List <String > getCommand() { 283 284 List <String > cmd = new ArrayList <String >(); 285 cmd.add(javaExe); 286 287 if (null != properties) { 288 for (Map.Entry <String , String > entry : properties.entrySet()) { 289 cmd.add("-D" + entry.getKey() + "=" + entry.getValue()); 290 } 291 } 292 293 cmd.add("-ea"); 294 cmd.add("-classpath"); 295 296 ClassLoader loader = this.getClass().getClassLoader(); 297 StringBuffer classpath = new StringBuffer (System.getProperty("java.class.path")); 298 if (loader instanceof URLClassLoader ) { 299 URLClassLoader urlloader = (URLClassLoader )loader; 300 for (URL url : urlloader.getURLs()) { 301 classpath.append(File.pathSeparatorChar); 302 classpath.append(url.getFile()); 303 } 304 } 305 cmd.add(classpath.toString()); 306 307 cmd.add("-Djavax.xml.ws.spi.Provider=org.objectweb.celtix.bus.jaxws.spi.ProviderImpl"); 308 309 String loggingPropertiesFile = System.getProperty("java.util.logging.config.file"); 310 if (null != loggingPropertiesFile) { 311 cmd.add("-Djava.util.logging.config.file=" + loggingPropertiesFile); 312 } 313 314 cmd.add(className); 315 316 if (null != serverArgs) { 317 for (String s : serverArgs) { 318 cmd.add(s); 319 } 320 } 321 322 return cmd; 323 } 324 325 static class Mutex { 326 } 328 329 static class TimeoutCounter { 330 private final long expectedEndTime; 331 332 public TimeoutCounter(long theExpectedTimeout) { 333 expectedEndTime = System.currentTimeMillis() + theExpectedTimeout; 334 } 335 336 public boolean isTimeoutExpired() { 337 return System.currentTimeMillis() > expectedEndTime; 338 } 339 } 340 } 341 | Popular Tags |