2

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

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

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

--StartMethod参数说明如下:

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

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

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

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

此致

4

1 回答 1

2

对于记录:

我是否必须使用 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.stackoverflow.questions.31556478.ServiceLauncher ^
    --StartParams="@@PUT_ANY_START_ARGUMENTS_HERE@@" ^
    --StartMethod=start ^
    --StopMode=jvm ^
    --StopClass=com.stackoverflow.questions.31556478.ServiceLauncher ^
    --StopMethod=stop

在此之后,服务可以通过

prunsrv //ES//MyTestSevice


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

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

package com.stackoverflow.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();
      }
    }
  }
}
于 2015-09-02T11:57:39.570 回答