Java执行外部程序(Apache Commons Exec)

原创 2015年07月07日 11:58:59

之前使用Runtime.getRuntime().exec调用外部程序,在Tomcat下会有当前线程一直等待的现象。当时为了解决这个问题,使用新建线程接收外部程序的输出信息,详情请看博客http://blog.csdn.net/accountwcx/article/details/46785437


后来在网上找到开源的Java调用外部程序类库Apache Commons Exce,这个类库提供非阻塞方法调用外部程序。

官方网址 http://commons.apache.org/proper/commons-exec/

maven地址 http://mvnrepository.com/artifact/org.apache.commons/commons-exec/1.3

官方教程 http://commons.apache.org/proper/commons-exec/tutorial.html 官方教程提供的非阻塞方法在1.3版中不适用


Commons Exec对调用外部程序进行了封装,只需要少量代码即可实现外部程序调用,如执行命令"AcroRd32.exe /p /h c:\help.pdf"。

String line = "AcroRd32.exe /p /h c:\help.pdf";
CommandLine cmdLine = CommandLine.parse(line);
DefaultExecutor executor = new DefaultExecutor();

//设置命令执行退出值为1,如果命令成功执行并且没有错误,则返回1
executor.setExitValue(1);

int exitValue = executor.execute(cmdLine);

Commons Exec支持通过添加参数方式构建命令,执行命令"AcroRd32.exe /p /h c:\help.pdf"也可以按如下方法创建。

CommandLine cmdLine = new CommandLine("AcroRd32.exe");
cmdLine.addArgument("/p");
cmdLine.addArgument("/h");

Map map = new HashMap();
map.put("file", new File("c:\help.pdf"));
cmdLine.addArgument("${file}");
cmdLine.setSubstitutionMap(map);

DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(1);
int exitValue = executor.execute(cmdLine);

Commons Exec支持设置外部命令执行等待时间,如果超过等等时间则中断执行。

CommandLine cmdLine = new CommandLine("AcroRd32.exe");
cmdLine.addArgument("/p");
cmdLine.addArgument("/h");

Map map = new HashMap();
map.put("file", new File("c:\help.pdf"));
cmdLine.addArgument("${file}");
cmdLine.setSubstitutionMap(map);

DefaultExecutor executor = new DefaultExecutor();

//创建监控时间60秒,超过60秒则中端执行
ExecuteWatchdog watchdog = new ExecuteWatchdog(60*1000);
executor.setWatchdog(watchdog);

executor.setExitValue(1);
int exitValue = executor.execute(cmdLine);

上面的执行外部命令都是阻塞式,也就是在执行外部命令时,当前线程是阻塞的。如果不想在执行外部命令的时候,把当前线程阻塞,可以使用DefaultExecuteResultHandler处理外部命令执行的结果,释放当前线程。

CommandLine cmdLine = new CommandLine("AcroRd32.exe");
cmdLine.addArgument("/p");
cmdLine.addArgument("/h");

Map map = new HashMap();
map.put("file", new File("c:\help.pdf"));
cmdLine.addArgument("${file}");
cmdLine.setSubstitutionMap(map);

DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(1);
executor.execute(cmdLine, resultHandler);
resultHandler.waitFor();


博客http://blog.csdn.net/accountwcx/article/details/46785437的HtmlToPdf类可以改成如下。

import java.io.File;

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecuteResultHandler;
import org.apache.commons.exec.DefaultExecutor;

public class HtmlToPdf {
	//wkhtmltopdf在系统中的路径
	private static final String toPdfTool = "c:\\wkhtmltopdf.exe";
	
	/**
	 * @param srcPath html路径,可以本地硬盘路径或者url
	 * @param destPath pdf保存路径
	 * @return 转换成功返回true
	 */
	public static boolean convert(String srcPath, String destPath){		
		File file = new File(destPath);
		File parent = file.getParentFile();
		//如果pdf保存路径不存在,则创建路径
		if(!parent.exists()){
			parent.mkdirs();
		}
		
		CommandLine cmdLine = new CommandLine(toPdfTool);
		cmdLine.addArgument(srcPath, true);
		cmdLine.addArgument(destPath, true);
		
		DefaultExecutor executor = new DefaultExecutor();
		
		//设置执行命令成功的退出值为1
		executor.setExitValue(1);
		
		//非阻塞
		DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
		
		boolean result = true;
		try {
			executor.execute(cmdLine, resultHandler);
			resultHandler.waitFor();
		} catch (Exception e) {
			result = false;
			e.printStackTrace();
		}
		
		return result;
	}
}



相关文章推荐

使用Apache Commons Exec管理进程

网上竟然搜不到详细一点的帖子,估计大家用JAVA去管理进程的场景比较少吧,只好自己总结一个。Java管理进程,API级别是使用:Runtime.getRuntime().exec(“shell”); ...
  • fd_mas
  • fd_mas
  • 2015年12月02日 14:21
  • 2196

利用Apache Commons Exec调用命令行并取得命令行的输出(实例)

public String ping(String ip) { try { String command = "ping "+ip; ...

common-exec调用进程命令

package org.sf.exec; import java.io.File; import java.io.IOException; import java.util.HashMap;...

Apache commons exec 简介和简单ping命令方法调用实现

Apache commonsexec提供一些常用的方法用来执行外部进程。Apache commons exec库提供了监视狗Watchdog来设监视进程的执行超时,同时也还实现了同步和异步功能。 A...
  • ffm83
  • ffm83
  • 2014年12月30日 15:09
  • 1514

Java执行外部程序(Apache Commons Exec)

之前使用Runtime.getRuntime().exec调用外部程序,在Tomcat下会有当前线程一直等待的现象。当时为了解决这个问题,使用新建线程接收外部程序的输出信息,详情请看博客http://...

JAVA基础应用——执行外部程序(Apache Commons Exec)

Runtime.getRuntime().exec调用外部程序,在Tomcat下会有当前线程一直等待的现象。Apache Commons Exec是一个开源的Java调用外部程序类库,提供阻塞和非阻塞...
  • xundh
  • xundh
  • 2017年05月27日 15:03
  • 317

Apache common exec包的相应使用总结

最近在写一个Java工具,其中调用了各种SHELL命令,使用了Runtime.getRuntime().exec(command);这个方法。但是在我调用某个命令执行操作时,程序就卡在那了,但是其他操...
  • clamaa
  • clamaa
  • 2017年04月11日 09:57
  • 245

利用Apache commons exec 实现指定应用打开对应文件

在实际工作中,我们有时候需要指定某一个应用,打开某一个文件。比如用播放器打开一个MP3音乐文件,用记事本打开一个文本文件。不过有的应用需要一些额外的参数,在具体使用的时候要注意。   packag...
  • ffm83
  • ffm83
  • 2014年12月30日 15:10
  • 1203

Java调用命令行并获取执行结果

import java.io.BufferedReader; import java.io.InputStreamReader; public class Command { public sta...
  • prstaxy
  • prstaxy
  • 2014年06月11日 13:52
  • 26446

java.lang.NoClassDefFoundError: org/apache/commons/lang/StringUtils

今天头一次试struts2,结果控制台显示错误java.lang.NoClassDefFoundError: org/apache/commons/lang/StringUtils,找吧,在strut...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java执行外部程序(Apache Commons Exec)
举报原因:
原因补充:

(最多只允许输入30个字)