View Javadoc

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 }