思路:
java代码可以通过Runtime.getRuntime().exec(“cmd命令行”) 来执行cmd命令 因此,我们可以通过此方法来让java操作tomcat的启动
- 1 执行启动的cmd命令如下(先定位到tomcat bin目录下,再执行启动命令):
cmd /c cd " + startPath + " && catalina.bat run
其中startPath为tomcat的bin目录路径,例如我的路径为:D:\apache-tomcat-9.0.10\bin
命令采用catalina.bat run 而不是startup.bat的原因是前者可以通过结果流得到tomcat控制台信息,而后者不能
- 2 通过Runtime.getRuntime().exec(“cmd命令行”)执行命令时程序阻塞问题解决
执行此方法时因为其自身会产生标准错误流,而其给流的分配内存很少,所以当标准错误流太多时,就会造成阻塞,
此问题的解决是单独开一个线程去输出标准错误流,这样就不会造成主程序的阻塞,详细见下面代码的printTomcatConsolMessage方法 - 3 启动tomcat时标准错误流是另起线程的,那么如何通过捕获的信息获知tomcat是否启动完毕
此问题的处理方式是加CountDownLatch 其是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信,
本身类似于定时器的功能,达到当子线程进行到一定条件时,定时器清零,主线程就接着执行,详见代码 - 4 tomcat启动、停止工具类代码
代码实现:
/**
* 通过java代码控制指定位置的tomcat的启动或关闭
*/
public class TomcatServer {
static Logger logger = LoggerFactory.getLogger(TomcatServer.class);
/**
* 启动tomcat
*
* @param tomcatRootPath 启动tomcat根路径
* @return
*/
public static ResultObject start(String tomcatRootPath) {
final ResultObject resultObject = new ResultObject();
resultObject.setResult(false);
if (StringUtils.isBlank(tomcatRootPath)) {
return resultObject;
}
//Address already in use: bind
//Server startup in 16546 ms
String startPath = tomcatRootPath + "\\bin";
BufferedReader in = null;
// 启动tomcat命令
String execCommond = "cmd /c cd " + startPath + " && catalina.bat ru