使用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服務的時候,並不會出現這個問題。