如題,怎樣將Java程序變身爲Windows服務,不要跟我說Win接口,我不熟。 php
即將java啓動批處理命令編譯爲win程序,可經過 批處理潛行者V6.0或 quickbfc 3.6.1實現; html
而後利用系統自帶的sc命令將其建立爲系統服務:(這裏爲了測試效果,我加上了交互式運行服務的參數) java
sc create test binPath= "C:\FFE.exe" type= own type= interact start= auto
注意,坑跌的windows命令一貫是不走尋常路: shell
Using some of the options will trigger a "[SC] CreateService FAILED 87" this usually means the option used like "type" needs another declaration. In case for instance when using type= interact, the type= option must be declared again with an alternative type like own. So effectivly the service type will be type= own interactive.
建立完成以後就能夠啓動服務:net start test apache
發現程序正常啓動了,可是服務一直是啓動狀態,把程序關閉後,服務又變成了中止狀態。Why? windows
由於系統服務並不知道你程序啓動到什麼狀態纔算是啓動成功,也不知道程序中止是正常結束仍是異常退出。 tomcat
歸根結底,就是經過sc命令將通常程序添加爲系統服務的方式沒有實現Win服務接口,不知足做爲一個標準的daemon程序的條件。 app
在網上搜索一番,發現還有微軟的開發工具能夠利用:使用srvany.exe將任何程序做爲Windows服務運行 eclipse
上面這篇文章寫得很棒,做者還開發了一個輕巧的工具SrvanyUI方便建立自定義服務。 jvm
可是我通過試驗沒有成功,緣由不明。後臺監控發現java程序閃現以後迅速關閉,多是由於classpath設置錯誤。
總而言之,這種方式仍是不夠靈活,出錯沒有任何提示,只能經過經驗去排錯;
另外,如文中所說,該工具已不被微軟支持了,而且win7以上的版本可能會出現兼容問題。
How to create a windows service from java app?
各類牛人都在這篇問答裏發表了他們的見解:
JSW我使用了較長的時間,穩定性和擴展性都不錯,高級版本還提供了對Java異常的處理,好比OOM產生時能夠選擇是否自動重啓服務。
但不足之處是,收費、64位版本須要購買Licence。放在5年前,或許不用擔心是否須要64位JVM,但現在,32位僅1.5G的堆內存略顯不足。
一個 wrapper.conf配置文件示例以下:(官方下載包有更詳細的例子和說明)
wrapper.java.command="C:\Program Files\Java\jdk1.7.0_72\bin\java" wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp wrapper.java.classpath.1=../test.jar wrapper.java.classpath.2=wrapper.jar wrapper.java.classpath.3=../lib/* wrapper.java.library.path.1=. wrapper.java.additional.1= -Xms512m wrapper.java.additional.2= -Xmx512m wrapper.java.initmemory=256 wrapper.java.maxmemory=512 wrapper.app.parameter.1=test.Main wrapper.app.parameter.2=arg1 wrapper.console.format=PM wrapper.console.loglevel=INFO wrapper.logfile=../log/test.log wrapper.logfile.format=LPTM wrapper.logfile.loglevel=INFO wrapper.logfile.maxsize=0 wrapper.logfile.maxfiles=0 wrapper.syslog.loglevel=NONE wrapper.console.title=Test_Service wrapper.ntservice.name=Test_Service wrapper.ntservice.displayname=Test_Service wrapper.ntservice.description=Test_Service wrapper.ntservice.dependency.1= wrapper.ntservice.starttype=AUTO_START wrapper.ntservice.interactive=false
或許YAJSW出現就是爲了替換JSW,由於它是開源免費的,且支持從JSW快速無縫遷移。可是,有個哥們都說被它19M的下載包給嚇到了…因此……
如下工具本人並未測試,但不表明不適用:
javaservice(06年後未更新,使用方法不詳)
Java Service Launcher(小巧,支持64位JVM以及JRockit等第三方虛擬機,惋惜文檔比較簡陋)
Launch4j,一個將Jar打包爲exe的工具,惋惜的是使用XML配置,我的無感
更多開源工具見:Java開源打包工具
先來講說情懷:Tomcat,相信不少同窗從第一天學習Java的時候就開始熟知。看到ACD的圖標後才發現,原來Tomcat win安裝版就是用的它!
再來講說用法:Win版的入口程序是procrun,用它來建立一個服務是如此之簡單:
set APP_HOME=D:\ set JAVA_HOME="C:\Program Files\Java\jdk1.7.0_72\" set PR_CLASSPATH=%APP_HOME%\test.jar;%APP_HOME%\lib\* REM 建立服務 prunsrv //IS//test_service --DisplayName=test_service --Install=%APP_HOME%\bin\prunsrv.exe --StartMode=jvm --StopMode=jvm --Startup=auto --JavaHome=%JAVA_HOME% --JvmMs=2048 --JvmMx=2048 --JvmSs=128 ++JvmOptions=-server;-XX:+UseParallelGC;-XX:ParallelGCThreads=4;-XX:+UseParallelOldGC;-XX:+UseAdaptiveSizePolicy --Classpath=%CP%" --StartClass=com.test.Main --StopClass=com.test.Main --StopMethod=stop --LogPath=%APP_HOME%\log --StdOutput=auto --StdError=auto REM 刪除服務 prunsrv //DS//test_service
參數不少,看看註釋就明白了,這裏也有中文翻譯:Commons Daemon 之 procrun。
此外,Wiki頁上有一些答問和一個Java主程序栗子。有幾點須要注意的是:
public static void stop(String[] args) { System.out.println("服務關閉了"); System.exit(0); }
Procrun不只可將Java類生成服務,也可將exe變爲服務,詳見參數設置。
參考:用common-deamon構建java後臺服務、Windows 64位環境的Java 服務配置
先來講說它的弊端:須要一個入口類,依賴WinRun4J.jar包,相比ACD有必定耦合度,而非直接用主啓動類。除此以外,一切看起來都不錯~
The only drawback is that it requires a special class for working as a service (instead of simply calling standard main class)官網上有個生成服務的栗子,下載的包裏也有,可是都有點問題:
import org.boris.winrun4j.AbstractService; import org.boris.winrun4j.EventLog; import org.boris.winrun4j.ServiceException; public class ServiceTest extends AbstractService { public int serviceMain(String[] args) throws ServiceException { int count = 0; while (!shutdown) { try { Thread.sleep(1000); } catch (InterruptedException e) { } if (++count % 10 == 0) { EventLog.report("test", EventLog.INFORMATION, "test..." + count); System.out.println("test log...." + count); } } System.out.println("service shutdown..."); return 0; } public boolean isShutdown() { System.out.println("isShutdown called..."); return super.isShutdown(); } }
上面類中調用 EventLog.report方法生成的日誌只會寫到系統日誌裏,只有在 計算機管理 - 系統工具 - 事件查看器 - 應用程序 中才能看到
對應的日誌文件在XP系統中的位置是:C:\WINDOWS\system32\config\SysEvent.Evt
顯然咱們更但願日誌可控,而不是被操做系統接管。可是我沒有找到合適的參數來設置,只能經過Java程序來指定。
將上面的類編譯後生成class文件,而後再來編輯配置文件WinRun4Jc.ini:
service.class=ServiceTest service.id=WinRun4J_Test service.name=WinRun4J_Test service.description=test WinRun4J. classpath.1=. classpath.2=D:\winrun4j\bin\WinRun4J.jar log=test.log
注意了:
經過如下命令建立和刪除服務:
WinRun4Jc --WinRun4J:RegisterService WinRun4Jc --WinRun4J:UnregisterService
WinRun4J還提供了Eclipse插件以及給exe程序增長ico圖標的小工具,用法很簡單,官網上也有說明。
無論怎麼說,WinRun4J至關於ACD和 Launch4j的合體,雖然總體功能沒有二者強大,可是也都作得不錯,
尤爲是對於使用eclipse的同窗但是方便了很多,看看它貼心的導出功能便可見一斑: