View Javadoc
1   package org_scala_tools_maven_executions;
2   
3   import java.io.File;
4   import java.util.ArrayList;
5   import java.util.List;
6   
7   import org.apache.commons.exec.CommandLine;
8   import org.apache.commons.exec.DefaultExecutor;
9   import org.apache.commons.exec.ExecuteException;
10  import org.apache.commons.exec.Executor;
11  import org.apache.commons.exec.LogOutputStream;
12  import org.apache.commons.exec.OS;
13  import org.apache.commons.exec.PumpStreamHandler;
14  import org.apache.maven.plugin.AbstractMojo;
15  import org.apache.maven.plugin.MojoFailureException;
16  import org.codehaus.plexus.util.StringUtils;
17  
18  /**
19   * forked java commands.
20   *
21   * @author D. Bernard
22   * @author J. Suereth
23   */
24  public class JavaMainCallerByFork extends JavaMainCallerSupport {
25  
26      private boolean _forceUseArgFile = false;
27  
28      /**
29       * Location of java executable.
30       */
31      private String _javaExec;
32  
33      private boolean _redirectToLog;
34  
35      public JavaMainCallerByFork(AbstractMojo requester, String mainClassName, String classpath, String[] jvmArgs, String[] args, boolean forceUseArgFile) throws Exception {
36          super(requester, mainClassName, classpath, jvmArgs, args);
37          for (String key : System.getenv().keySet()) {
38              env.add(key + "=" + System.getenv(key));
39          }
40          _javaExec = System.getProperty("java.home");
41          if (_javaExec == null) {
42              _javaExec = System.getenv("JAVA_HOME");
43              if (_javaExec == null) {
44                  throw new IllegalStateException("Couldn't locate java, try setting JAVA_HOME environment variable.");
45              }
46          }
47          _javaExec += File.separator + "bin" + File.separator + "java";
48          _forceUseArgFile = forceUseArgFile;
49      }
50  
51      public boolean run(boolean displayCmd, boolean throwFailure) throws Exception {
52          List<String> cmd = buildCommand();
53          displayCmd(displayCmd, cmd);
54          Executor exec = new DefaultExecutor();
55  
56          //err and out are redirected to out
57          if (!_redirectToLog) {
58              exec.setStreamHandler(new PumpStreamHandler(System.out));
59          } else {
60              exec.setStreamHandler(new PumpStreamHandler(new LogOutputStream() {
61  
62                  @Override
63                  protected void processLine(String line, @SuppressWarnings("unused") int level) {
64                      if (line.toLowerCase().indexOf("error") > -1) {
65                          requester.getLog().error(line);
66                      } else if (line.toLowerCase().indexOf("warn") > -1) {
67                          requester.getLog().warn(line);
68                      } else {
69                          requester.getLog().info(line);
70                      }
71                  }
72              }));
73          }
74  
75          CommandLine cl = new CommandLine(cmd.get(0));
76          for (int i = 1; i < cmd.size(); i++) {
77              cl.addArgument(cmd.get(i));
78          }
79          try {
80              int exitValue = exec.execute(cl);
81              if (exitValue != 0) {
82                  if (throwFailure) {
83                      throw new MojoFailureException("command line returned non-zero value:" + exitValue);
84                  }
85                  return false;
86              }
87              return true;
88          } catch (ExecuteException exc) {
89              if (throwFailure) {
90                  throw exc;
91              }
92              return false;
93          }
94      }
95  
96      public SpawnMonitor spawn(boolean displayCmd) throws Exception {
97          List<String> cmd = buildCommand();
98          File out = new File(System.getProperty("java.io.tmpdir"), mainClassName +".out");
99          out.delete();
100         cmd.add(">"+ out.getCanonicalPath());
101         File err = new File(System.getProperty("java.io.tmpdir"), mainClassName +".err");
102         err.delete();
103         cmd.add("2>"+ err.getCanonicalPath());
104         List<String> cmd2 = new ArrayList<String>();
105         String cmdStr = StringUtils.join(cmd.iterator(), " ");
106         if (OS.isFamilyDOS()) {
107             cmd2.add("cmd.exe");
108             cmd2.add("/C");
109             cmd2.add(cmdStr);
110         } else {
111             cmd2.add("/bin/sh");
112             cmd2.add("-c");
113             cmd2.add(cmdStr);
114         }
115         displayCmd(displayCmd, cmd2);
116         ProcessBuilder pb = new ProcessBuilder(cmd2);
117         //pb.redirectErrorStream(true);
118         final Process p = pb.start();
119         return new SpawnMonitor(){
120             public boolean isRunning() throws Exception {
121                 try {
122                     p.exitValue();
123                     return false;
124                 } catch(IllegalThreadStateException e) {
125                     return true;
126                 }
127             }
128         };
129     }
130 
131     private void displayCmd(boolean displayCmd, List<String> cmd) {
132         if (displayCmd) {
133             requester.getLog().info("cmd: " + " " + StringUtils.join(cmd.iterator(), " "));
134         } else if (requester.getLog().isDebugEnabled()) {
135             requester.getLog().debug("cmd: " + " " + StringUtils.join(cmd.iterator(), " "));
136         }
137     }
138 
139     protected List<String> buildCommand() throws Exception {
140         ArrayList<String> back = new ArrayList<String>(2 + jvmArgs.size() + args.size());
141         back.add(_javaExec);
142         if (!_forceUseArgFile && (lengthOf(args, 1) + lengthOf(jvmArgs, 1) < 400)) {
143             back.addAll(jvmArgs);
144             back.add(mainClassName);
145             back.addAll(args);
146         } else {
147             File jarPath = new File(MainHelper.locateJar(MainHelper.class));
148             requester.getLog().debug("plugin jar to add :" + jarPath);
149             addToClasspath(jarPath);
150             back.addAll(jvmArgs);
151             back.add(MainWithArgsInFile.class.getName());
152             back.add(mainClassName);
153             back.add(MainHelper.createArgFile(args).getCanonicalPath());
154         }
155         return back;
156     }
157 
158     private long lengthOf(List<String> l, long sepLength) throws Exception {
159         long back = 0;
160         for (String str : l) {
161             back += str.length() + sepLength;
162         }
163         return back;
164     }
165 
166     public void redirectToLog() {
167         _redirectToLog = true;
168     }
169 }