1. 程式人生 > >Java執行外部程式(Apache Commons Exec)

Java執行外部程式(Apache Commons Exec)

之前使用Runtime.getRuntime().exec呼叫外部程式,在Tomcat下會有當前執行緒一直等待的現象。當時為了解決這個問題,使用新建執行緒接收外部程式的輸出資訊,詳情請看部落格http://blog.csdn.net/accountwcx/article/details/46785437

後來在網上找到開源的Java呼叫外部程式類庫Apache Commons Exce,這個類庫提供非阻塞方法呼叫外部程式。

Commons Exec對呼叫外部程式進行了封裝,只需要少量程式碼即可實現外部程式呼叫,如執行命令"AcroRd32.exe /p /h c:\help.pdf"。

  1. String line = 
    "AcroRd32.exe /p /h c:\help.pdf";  
  2. CommandLine cmdLine = CommandLine.parse(line);  
  3. DefaultExecutor executor = new DefaultExecutor();  
  4. //設定命令執行退出值為1,如果命令成功執行並且沒有錯誤,則返回1
  5. executor.setExitValue(1);  
  6. int exitValue = executor.execute(cmdLine);  

Commons Exec支援通過新增引數方式構建命令,執行命令"AcroRd32.exe /p /h c:\help.pdf"也可以按如下方法建立。

  1. CommandLine cmdLine = new CommandLine("AcroRd32.exe");  
  2. cmdLine.addArgument("/p");  
  3. cmdLine.addArgument("/h");  
  4. Map map = new HashMap();  
  5. map.put("file"new File("c:\help.pdf"));  
  6. cmdLine.addArgument("${file}");  
  7. cmdLine.setSubstitutionMap(map);  
  8. DefaultExecutor executor = new DefaultExecutor();  
  9. executor.setExitValue(1);  
  10. int exitValue = executor.execute(cmdLine);  

Commons Exec支援設定外部命令執行等待時間,如果超過等等時間則中斷執行。
  1. CommandLine cmdLine = new CommandLine("AcroRd32.exe");  
  2. cmdLine.addArgument("/p");  
  3. cmdLine.addArgument("/h");  
  4. Map map = new HashMap();  
  5. map.put("file"new File("c:\help.pdf"));  
  6. cmdLine.addArgument("${file}");  
  7. cmdLine.setSubstitutionMap(map);  
  8. DefaultExecutor executor = new DefaultExecutor();  
  9. //建立監控時間60秒,超過60秒則中端執行
  10. ExecuteWatchdog watchdog = new ExecuteWatchdog(60*1000);  
  11. executor.setWatchdog(watchdog);  
  12. executor.setExitValue(1);  
  13. int exitValue = executor.execute(cmdLine);  

上面的執行外部命令都是阻塞式,也就是在執行外部命令時,當前執行緒是阻塞的。如果不想在執行外部命令的時候,把當前執行緒阻塞,可以使用DefaultExecuteResultHandler處理外部命令執行的結果,釋放當前執行緒。
  1. CommandLine cmdLine = new CommandLine("AcroRd32.exe");  
  2. cmdLine.addArgument("/p");  
  3. cmdLine.addArgument("/h");  
  4. Map map = new HashMap();  
  5. map.put("file"new File("c:\help.pdf"));  
  6. cmdLine.addArgument("${file}");  
  7. cmdLine.setSubstitutionMap(map);  
  8. DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();  
  9. DefaultExecutor executor = new DefaultExecutor();  
  10. executor.setExitValue(1);  
  11. executor.execute(cmdLine, resultHandler);  
  12. resultHandler.waitFor();  


  1. import java.io.File;  
  2. import org.apache.commons.exec.CommandLine;  
  3. import org.apache.commons.exec.DefaultExecuteResultHandler;  
  4. import org.apache.commons.exec.DefaultExecutor;  
  5. publicclass HtmlToPdf {  
  6.     //wkhtmltopdf在系統中的路徑
  7.     privatestaticfinal String toPdfTool = "c:\\wkhtmltopdf.exe";  
  8.     /** 
  9.      * @param srcPath html路徑,可以本地硬碟路徑或者url 
  10.      * @param destPath pdf儲存路徑 
  11.      * @return 轉換成功返回true 
  12.      */
  13.     publicstaticboolean convert(String srcPath, String destPath){       
  14.         File file = new File(destPath);  
  15.         File parent = file.getParentFile();  
  16.         //如果pdf儲存路徑不存在,則建立路徑
  17.         if(!parent.exists()){  
  18.             parent.mkdirs();  
  19.         }  
  20.         CommandLine cmdLine = new CommandLine(toPdfTool);  
  21.         cmdLine.addArgument(srcPath, true);  
  22.         cmdLine.addArgument(destPath, true);  
  23.         DefaultExecutor executor = new DefaultExecutor();  
  24.         //設定執行命令成功的退出值為1
  25.         executor.setExitValue(1);  
  26.         //非阻塞
  27.         DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();  
  28.         boolean result = true;  
  29.         try {  
  30.             executor.execute(cmdLine, resultHandler);  
  31.             resultHandler.waitFor();  
  32.         } catch (Exception e) {  
  33.             result = false;  
  34.             e.printStackTrace();  
  35.         }  
  36.         return result;  
  37.     }  
  38. }