【问题标题】:Howto setup a Daemon implementation as windows service如何将守护程序实现设置为 Windows 服务
【发布时间】:2015-07-22 07:24:57
【问题描述】:

我没有找到任何关于如何将实现org.apache.commons.daemon.Daemon 接口的类注册为 Windows 服务的非常好的示例(实际上我没有找到一个示例)。

我必须使用 procrun 注册这个实现吗?但是实现接口似乎没有意义,因为 procrun 可以将任何程序注册为 Windows 服务。

此外,procrun 页面上似乎有一个文档错误 (http://commons.apache.org/proper/commons-daemon/procrun.html):

--StartMethod 参数说明:

注意:在 jvm 模式下,start 方法不应该在 stop 方法被调用之前返回。

但在“在 jvm 模式下使用 Procrun”部分的页面下方:

注意,处理服务启动的方法应该创建并启动一个单独的线程来进行处理,然后返回。 start 和 stop 方法是从不同的线程调用的。

我读错了还是有点矛盾?静态 start(String[] args) 方法的正确行为是什么?

最好的问候

【问题讨论】:

    标签: java windows-services apache-commons-daemon


    【解决方案1】:

    记录:

    我必须使用 procrun 注册这个实现吗?但是实现接口似乎没有意义,因为 procrun 可以将任何程序注册为 Windows 服务。

    是的,该服务需要使用 prunsrv 在 Windows 中注册。例如以下调用:

    prunsrv.exe //IS//MyTestService ^
        --DisplayName="My Test Service" --Description="Doesn't really do anything" ^
        --Install=@@PATH_TO_PRUNSRV@@\prunsrv.exe ^
        --Startup=manual ^
        --Jvm=auto ^
        --Classpath="@@PUT_FULL_CLASSPATH_HERE@@" ^
        --StartMode=jvm ^
        --StartClass==com.*.questions.31556478.ServiceLauncher ^
        --StartParams="@@PUT_ANY_START_ARGUMENTS_HERE@@" ^
        --StartMethod=start ^
        --StopMode=jvm ^
        --StopClass=com.*.questions.31556478.ServiceLauncher ^
        --StopMethod=stop
    

    在此之后服务可以通过

    prunsrv //ES//MyTestSevice
    


    静态 start(String[] args) 方法的正确行为是什么?

    测试这两种变体,只有实现工作有效,它停留在 start-method 中并且没有产生额外的线程。这是一个可以通过上述 prunsrv 调用注册的启动器实现看起来像这样(没有任何保证):

    package com.*.questions.31556478;
    
    import java.util.Arrays;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class ServiceLauncher
    {
      private static final Logger LOGGER = LoggerFactory.getLogger(ServiceLauncher.class);
    
      private static SomeServer mServer;
    
      public static void start(final String[] args)
      {
        LOGGER.debug("Start called: {}", Arrays.toString(args));
    
        try
        {
          mServer = new SomeServer(args);
          mServer.start();
        }
        catch (final Exception e)
        {
          LOGGER.error("Terminating due to Exception: ", e);
        }
      }
    
      public static void stop(final String[] args) throws Exception
      {
        LOGGER.debug("Stop called: {}", Arrays.toString(args));
    
        synchronized (ServiceLauncher.class)
        {
          if (mServer != null)
          {
            mServer.stop();
          }
        }
      }
    }
    

    【讨论】:

      最近更新 更多