1 /** 2 * 3 * Copyright 2004 The Apache Software Foundation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.geronimo.gbuild.agent; 18 19 import org.codehaus.plexus.logging.AbstractLogEnabled; 20 import org.codehaus.plexus.util.cli.CommandLineException; 21 import org.codehaus.plexus.util.cli.CommandLineUtils; 22 import org.codehaus.plexus.util.cli.Commandline; 23 24 import java.io.File; 25 import java.util.Map; 26 import java.util.List; 27 import java.util.ArrayList; 28 29 /** 30 * @version $Rev$ $Date$ 31 */ 32 public class KillProcessesExtension extends AbstractLogEnabled implements BuildAgentExtension { 33 34 /** 35 * @plexus.requirement 36 */ 37 private BuildActivityNotifier notifier; 38 39 private String regex; 40 41 public void preProcess(Map build) { 42 } 43 44 public void postProcess(Map build, Map results) { 45 boolean isWindows = System.getProperty("os.name").startsWith("Windows"); 46 47 if (isWindows){ 48 return; 49 } 50 51 String[] ids = null; 52 53 List pids = null; 54 try { 55 pids = findProcessIds(regex); 56 } catch (Exception e) { 57 getLogger().warn("Failed to get a list of running processes. ", e); 58 return; 59 } 60 61 String processes = ""; 62 for (int i = 0; i < pids.size(); i++) { 63 String pid = (String) pids.get(i); 64 processes += pid +", "; 65 } 66 67 processes = processes.replaceAll(", $",""); 68 69 if (pids.size() > 0){ 70 71 String message = "Found " + pids.size()+ " processes matching \""+regex+"\" (" + processes + ")."; 72 73 results.put("header.hung-processes", processes); 74 getLogger().info(message); 75 notifier.sendNotification(build, message); 76 77 try { 78 killProcesses(pids); 79 } catch (Exception e) { 80 getLogger().error("Unable to kill "+pids.size()+" processes matching \""+regex+"\" (" + processes + ").", e); 81 } 82 83 } else { 84 getLogger().debug("No processes found matching \""+regex+"\"."); 85 } 86 } 87 88 public static void killProcesses(List pids) throws Exception { 89 ExecResult res = exec("kill", (String[]) pids.toArray(new String[]{})); 90 if (res.exitCode != 0){ 91 throw new IllegalStateException("Command returned error exit code " + res.exitCode + "."); 92 } 93 } 94 95 public static List findProcessIds(String regex) throws Exception { 96 ExecResult res = exec("sh", new String[]{"-c","\"ps ax\""}); 97 if (res.exitCode != 0){ 98 throw new IllegalStateException("Command returned error exit code " + res.exitCode + "."); 99 } 100 String stdout = res.getStdout(); 101 String[] lines = stdout.split("[\n\r]"); 102 List list = new ArrayList(); 103 for (int i = 0; i < lines.length; i++) { 104 String line = lines[i]; 105 if (line.matches(regex)){ 106 line = line.replaceFirst(" *",""); 107 String pid = line.split(" +")[0]; 108 list.add(pid); 109 } 110 } 111 return list; 112 } 113 114 public static class ExecResult { 115 private final int exitCode; 116 private final String stdout; 117 private final String stderr; 118 119 public ExecResult(int exitCode, String stdout, String stderr) { 120 this.exitCode = exitCode; 121 this.stdout = stdout; 122 this.stderr = stderr; 123 } 124 125 public int getExitCode() { 126 return exitCode; 127 } 128 129 public String getStdout() { 130 return stdout; 131 } 132 133 public String getStderr() { 134 return stderr; 135 } 136 } 137 138 public static ExecResult exec(String cmd, String[] arguments) throws CommandLineException { 139 Commandline commandline = new Commandline(); 140 commandline.setExecutable(cmd); 141 commandline.setWorkingDirectory(new File(".").getAbsolutePath()); 142 143 for (int i = 0; i < arguments.length; i++) { 144 commandline.createArgument().setLine(arguments[i]); 145 } 146 147 CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); 148 CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer(); 149 int exitCode = CommandLineUtils.executeCommandLine(commandline, stdout, stderr); 150 return new ExecResult(exitCode, stdout.getOutput(), stderr.getOutput()); 151 } 152 153 }