【开源自动化测试疑难FAQ】【框架】EXE/VBS/BAT/SHELL等文件的调用安全守护

        JAVA调用EXE/VBS/BAT/SHELL,有些时候需要waitfor,而用了waitfor的下场,不需要我多说家都知道,一般情况下会hang死,其主要原因是进程里累积的buffer信息太多,其默认的大小无法装载这么多字节。所以需要在waitfor之前去把这些信息逐个先读出来,以免其累积,所以需要另起一个读buffer信息的线程来作为守护;但是这个读取的线程本身是否安全也未可知,所以我们可以再加一个超时的守护线程,所以一共就有3个线程来完成一次调用操作,结束之后都自动销毁。

package com.star.frame.executor;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.TimeoutException;

public class ThreadExecutor{
	private long threadTimeOut = 60000;
	private long readTimeOut = 20000;

	/**
	 * set process execute timeout 
	 * @param timeOut timeout of milliseconds.
	 */
	public void setThreadTimeOut(long timeOut){
		this.threadTimeOut = timeOut;
	}

	/**
	 * set process buffer read timeout 
	 * @param timeOut timeout of milliseconds.
	 */
	public void setReadTimeOut(long timeOut){
		this.readTimeOut = timeOut;
	}
	
	/**
	 * execute exe/bat/shell string or file by java.
	 * 
	 * @param	command command to be executed
	 * @throws	RuntimeException
	 * @throws	TimeoutException
	 */
	public int executeCommands(String command) {
		try {
			Process process = Runtime.getRuntime().exec(command);
			ProcessListener listener = new ProcessListener(process);
			listener.start();
			
	        try {
	        	listener.join(threadTimeOut);
	            if (listener.exit != null){
	                return listener.exit;
	            } else{
	                throw new TimeoutException();
	            }
	        } catch (InterruptedException ex) {
	        	listener.interrupt();
	            Thread.currentThread().interrupt();
				throw new RuntimeException(ex);
	        } finally {
	            process.destroy();
	        }
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * execute vbs by java.
	 * 
	 * @param	command vbs file with params Object to be executed
	 * @throws	RuntimeException
	 * @throws	TimeoutException
	 */
	public int executeCommands(String[] command) {
		try {
			Process process = Runtime.getRuntime().exec(command);
			ProcessListener listener = new ProcessListener(process);
			listener.start();
			
	        try {
	        	listener.join(threadTimeOut);
	            if (listener.exit != null){
	                return listener.exit;
	            } else{
	                throw new TimeoutException();
	            }
	        } catch (InterruptedException ex) {
	        	listener.interrupt();
	            Thread.currentThread().interrupt();
				throw new RuntimeException(ex);
	        } finally {
	            process.destroy();
	        }
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	private class ProcessListener extends Thread {
		private Process process = null;
		public Integer exit = null;

		/**
		 * construct with parameter sets. 
		 * @param process the process instance.
		 */
		public ProcessListener(Process process) {
			this.process = process;
		}

		/**
		 * read inputstream before process.waitfor(). keep threads never hangs up.
		 */
		@Override
		public void run() {
			try {
				StreamReader reader = new StreamReader(process.getInputStream());
				reader.start();
				reader.join(readTimeOut);
				exit = process.waitFor();
			} catch (InterruptedException ignore) {
				return;
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
	}
	
	private class StreamReader extends Thread {
		private InputStream input;

		/**
		 * construct with parameter sets. 
		 * @param input the InputStream instance.
		 */
		public StreamReader(InputStream input) {
			this.input = input;
		}

		/**
		 * read inputstream and do buffer output write.
		 */
		@Override
		public void run() {
			try {
				InputStreamReader isReader = new InputStreamReader(input);
				BufferedReader bfRader = new BufferedReader(isReader);
				while(bfRader.readLine() != null){
				}
				bfRader.close();
				isReader.close();
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值