Java实现Windows系统服务 JavaService

本文介绍如何使用Java创建Windows系统服务。通过示例代码演示启动和停止服务的过程,并使用JavaService工具进行服务的安装与卸载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2010-03-04 20:47  8126人阅读  评论(12)  收藏  举报
 分类:

版权声明:本文为博主原创文章,未经博主允许不得转载。

Windows系统服务(NT服务)相对于普通应用程序最直接的一个优点是系统启动后就可直接运行而无需用户登录系统。事实上,作为服务器来使用的系统,通常也并不需要登录系统,这样不只是方便,也提升了系统的安全性。不过,通常情况下,Windows系统服务使用C或C++实现,而有些时候基于某些因素的考虑,我们期望使用Java来实现系统服务,可以借助开源的JavaService达到此目的。

以下演示其实现过程。

首先编写实现NT服务的Java类,以下的示例代码通过两个类来达到实现NT服务的目的。类TestService提供了NT服务启动及停止的控制方法,而类Service则实现了NT服务真正要完成的工作。类TestService及类Service的完整代码如下:

[java]  view plain copy
  1. package com.yanzhijun;  
  2.   
  3. import java.util.Calendar;  
  4.   
  5. public class TestService  
  6. {  
  7.     private static Thread thread=null;  
  8.     private static Service service = null;  
  9.   
  10.     /** 
  11.     * 退出服务方法(该方法必须有参数 String [] args) 
  12.     * @param args 
  13.     */  
  14.     public static void StopService(String[] args)  
  15.     {  
  16.         System.out.println("停止服务");  
  17.         service.setRunFlag(false);  
  18.     }  
  19.     /** 
  20.     * 启动服务方法(该方法必须有参数 String [] args) 
  21.     * @param args 
  22.     */  
  23.     public static void StartService(String[] args)  
  24.     {  
  25.         System.out.println("启动服务");  
  26.         // 产生服务线程  
  27.         service = new Service();  
  28.         thread=new Thread(service);  
  29.         try  
  30.         {  
  31.             // 将服务线程设定为用户线程,以避免StartService方法结束后线程退出  
  32.             thread.setDaemon(false);  
  33.             if(!thread.isDaemon())  
  34.             {  
  35.                 System.out.println("成功设定线程为用户线程!");  
  36.             }  
  37.   
  38.             //启动服务线程  
  39.             thread.start();  
  40.         }  
  41.         catch(SecurityException se)  
  42.         {  
  43.             System.out.println("线程类型设定失败!");  
  44.         }  
  45.     }  
  46. }  
  47. class Service implements Runnable  
  48. {  
  49.     private boolean runFlag = true;  
  50.   
  51.     /** 
  52.     * 设定服务线程运行标志值 
  53.     * @param runFlag 
  54.     */  
  55.     public synchronized void setRunFlag(boolean runFlag)  
  56.     {  
  57.         this.runFlag = runFlag;  
  58.     }  
  59.   
  60.     /** 
  61.     * 取得服务线程运行标志值 
  62.     * @param void 
  63.     */  
  64.     private synchronized boolean getRunFlag()  
  65.     {  
  66.         return runFlag;  
  67.     }  
  68.   
  69.     @Override  
  70.     public void run()   
  71.     {  
  72.         System.out.println("服务线程开始运行");  
  73.         while(getRunFlag())  
  74.         {  
  75.             Calendar cal = Calendar.getInstance();  
  76.             long mis = cal.getTimeInMillis();  
  77.             System.out.println("当前时间:" + mis);  
  78.             try   
  79.             {  
  80.                 Thread.sleep(1000*10);  
  81.             }   
  82.             catch (InterruptedException e)   
  83.             {  
  84.                 e.printStackTrace();  
  85.             }  
  86.         }  
  87.         System.out.println("服务线程结束运行");  
  88.     }  
  89. }  

类TestService中的方法StartService用于启动NT服务,而StopService方法则用于停止NT服务。从代码中可以看出方法StartService与StopService实际上是分别实现了启动线程与终止线程的功能,而这里的线程就是实现NT服务的线程。这里有两点要特别注意:

1.              方法StartService与StopService都拥有参数String[] args,在安装NT服务时,可以指定启动或停止服务的参数,这些指定的参数将可以通过String[] args传递给方法StartService与StopService。在本例中由于演示的功能较为简单,故而未曾使到该参数。

2.              在StartService方法中启动线程之前,有必要将线程设定为用户线程。其原因在于如果线程是一个后台线程,则当主程序结束后,JVM会自动退出,后台线程当然也就终止执行,而如果主程序结束时,还有用户线程在运行,则JVM不会自动退出,而是要等用户线程结束后才退出。因此,要保证NT服务正常运行,这一点也是要特别注意的。

类Service是实现NT服务的线程类,NT服务要完成的功能在方法run中完成,在示例中它仅仅输出了当前时间,在实际应用中应根据需要在其中完成更为复杂的功能。方法setRunFlag与getRunFlag分别用于设定线程是否运行的标志和取得该标志值。setRunFlag方法需要在类外被调用并通过设定不同的参数通知线程是否需要继续执行;getRunFlag方法则取得该标志,它只在方法run的循环中被调用,所以声明为私有方法。此外,由于在不同线程中对线程运行标志进行设定与读取,所以方法setRunFlag与getRunFlag被设定为同步方法。

代码编写完成后,执行编译过程,必要时还可以打包成jar文件。

随后的工作就是利用JavaService注册NT服务,JavaService是一个开源项目,其项目地址为http://javaservice.objectweb.org,打开该地址后下载JavaService压缩包,并将解压之后的JavaService.exe置于上述代码编译之后包所在的目录,或者将JavaService.exe所在目录添加到环境变量PATH之中。

JavaService一共提供了8个参数可供选择,其中我们只需要关心安装NT服务的-install参数和卸载NT服务的-uninstall参数。

使用-install参数安装NT服务时还需要提供与服务相关的其它一些参数,其命令格式如下:

JavaService -install service_name jvm_library [jvm_options]

        -start start_class [-method start_method] [-params (start_parameters)]

        [-stop start_class [-method stop_method] [-params (stop_parameters)]]

        [-out out_log_file] [-err err_log_file]

        [-current current_dir]

        [-path extra_path]

        [-depends other_service]

        [-auto | -manual]

        [-shutdown seconds]

        [-user user_name -password password]

        [-append | -overwrite]

        [-startup seconds]

        [-description service_desc]

相关参数的作用说明如下:

service_name: The name of the service.

 jvm_library:  The location of the JVM DLL used to run the service.

 jvm_option:   An option to use when starting the JVM, such as:

                       "-Djava.class.path=c:/classes" or "-Xmx128m".

 start_class:  The class to load when starting the service.

 start_method: The method to call in the start_class. default: main

 start_parameters:Parameter(s) to pass in to the start_method.

 stop_class:   The class to load when stopping the service.

 stop_method:  The method to call in the stop_class. default: main

 stop_parameters:      Parameter(s) to pass in to the stop_method.

 out_log_file: A file to redirect System.out into. (gets overwritten)

 err_log_file: A file to redirect System.err into. (gets overwritten)

 current_dir:  The current working directory for the service.

                       Relative paths will be relative to this directory.

 extra_path:   Path additions, for native DLLs etc. (no spaces)

 other_service:        Single service name dependency, must start first.

 auto / manual:        Startup automatic (default) or manual mode.

 seconds:      Java method processing time (startup:sleep, shutdown:timeout).

 user_name:    User specified to execute the service (user@domain).

 password:     Password applicable if user specified to run the service.

 append / overwrite:   Log file output mode, append (default) or overwrite.

 service_desc: Text describing installed service (quoted string, max 1024).

 

要安装前面我们用Java编写的NT服务,可以用以下命令完成:

JavaService.exe -install TJS "%JAVA_HOME%/jre/bin/server/jvm.dll" -Xmx128m -Djava.class.path=%CLASSPATH% -start com.yanzhijun.TestService -method StartService -stop com.yanzhijun.TestService -method StopService -out "%CD%/out.log" -err "%CD%/err.log" -current "%CD%" –auto

上述命令中用“%”包含的是环境变量,其中JAVA_HOME是JDK的安装目录,CLASSPATH是为类的查找路径,这两者与正常配置JDK保持一致即可。CD则是当前目录。

成功安装服务以后,可以用以下命令启动服务:

net start TJS

由于在安装服务时指定了auto参数,所以服务被设定为自动启动,因此机器重启后无需使用上述命令这个NT服务就会启动。

如果需要停止服务,可以使用下列命令:

net stop TJS

这样就可以正常地使用Java所编写的NT服务了,如果不需要该服务,则应将该服务卸载,卸载服务的命令相比安装要简单地多,其格式如下:

JavaService -uninstall service_name

例如要卸载刚才安装的名称为TJS的服务,可以执行以下命令:

JavaService -uninstall TJS

 

注意:Java代码所生成的NT服务类所存储的目录路径中不能包含中文,否则启动服务时会失败。

 

 

 

欢迎访问梦断酒醒的博客http://www.yanzhijun.com

 

0
0


  好久coding了,重新打开myeclipse,打开记载着点点滴滴的iteye博客,觉得不该忘掉这个伟大而又感动自己的时刻。  
  言归正传,windows服务是一个运行在操作系统后台的可执行程序(打开方式:win+r -> services.msc),我们日常用到的apache、mysql、tomcat等的启动和关闭都会封装成一个windows服务,随着计算机启动而启动,藏匿在后台,不影响用户的其它工作。 
  今天先分享一个入门级的java创建windows服务的例子。 
   
  1.打包成win服务的功能代码 LogService.java 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.text.SimpleDateFormat; 
import java.util.Calendar; 
public class Logservice { 
public static void main(String args[]){ 
Calendar cal = Calendar.getInstance(); 
String s =  "f:\\"+new SimpleDateFormat("yyyyMMddHHmmss").format(cal.getTime())+".txt"; 
System.out.println(s); 
File f = new File(s); 
try { 
FileOutputStream out = new FileOutputStream(f); 
} catch (FileNotFoundException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 





运行后在f:路径下创建一个日期记事本。 
   2.下载JavaService (http://javaservice.objectweb.org/)下载后解压即可。 
   3.执行创建win服务的命令。在cmd运行窗口,cd到JavaService的目录,输入JavaService.exe -install myService "%JAVA_HO 
ME%"\jre\bin\client\jvm.dll  -Djava.class.path="JAVA_HOME"\lib\tools.jar;F:\myec 
lipse3\javaservice\bin -start Logservice 
(其中,myService为创建的服务名称,%JAVA_HO 
ME%"\jre\bin\client\jvm.dll为jdk中jre的jvm虚拟机,F:\myec 
lipse3\javaservice\bin为我LogService.class的存在路径,请大家根据自己的类文件进行修改。 
需注意问题:JavaService 不支持C:Program Files中间的空格,所以找不到JVM;固尽量使用"JAVA_HOME",而不要直接用jdk的路径;使用%JAVA_HOME%时又必须在其上加双引号才行,即"%JAVA_HOME%") 


推荐相关博客:http://blog.youkuaiyun.com/wgw335363240/article/details/6440873 
http://www.open-java.com/a/200907/29171928.shtml 
分享到:   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值