如题,怎样将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的同窗但是方便了很多,看看它贴心的导出功能便可见一斑: