使用winsw(Github https://github.com/kohsuke/winsw)可以非常方便的将java应用转换成windows service服务部署在windows服务器上。
详细操作步骤可以搜索一下,文档比较丰富。
这里说一个我遇到的问题。当我按照文档说明每步骤都配置好之后,服务安装没有问题,然后在启动的时候,服务抛出异常"错误 1067:进程意外终止".
public class App
{
public static void main( String[] args ) throws IOException, InterruptedException {
Logger logger = LogUtil.getLogger();
logger.info("a");
logger.severe(new Date().toString());
}
}
原因在与java模块的main方法并不是阻塞式的。当服务在启动的时候,winsw会执行配置文件中的java -jar命令启动一个进程,并且会记录下这个进程的进程ID,之后还会有一系列的操作。我们这里的main方法并不是阻塞式的,java -jar启动了进程,winsw记住了进程ID,但当后续使用到这个进程信息的时候,发现这个进程已经终止了,所以就抛出了异常。
解决办法:进程要为阻塞式进程,即进程不能结束。如下代码就一切正常。
public static void main( String[] args ) throws IOException, InterruptedException {
Logger logger = LogUtil.getLogger();
logger.info("a");
logger.severe(new Date().toString());
while (true) {
logger.info("a");
logger.severe(new Date().toString());
Thread.sleep(10000);
}
}
注意阻塞式并不能用System.in.read()来实现,因为在非命令行环境下,这行代码是不会有任何运行结果的。
SpringBoot应用因为本身就是一个阻塞式的应用,所以给SpringBoot使用winsw工具创建windows服务的时候,并不会出现这个问题。