如何将守护程序实现设置为 windows 服务
Howto setup a Daemon implementation as windows service
我没有找到任何关于如何将实现 org.apache.commons.daemon.Daemon
接口的 class 注册为 Windows 服务的真正好的示例(实际上我没有找到一个示例) .
我必须使用 procrun 注册这个实现吗?但是似乎没有实现接口的意义,因为 procrun 可以将任何程序注册为 windows 服务。
此外,procrun 页面上似乎有一个文档错误 (http://commons.apache.org/proper/commons-daemon/procrun.html):
--StartMethod
参数的描述指出:
Note: in jvm mode, the start method should not return until the stop method has been called.
但在 "Using Procrun in jvm mode" 部分的页面下方:
Note that the method handling service start should create and start a separate thread to carry out the processing, and then return. The start and stop methods are called from different threads.
我是不是读错了,还是有点矛盾??静态 start(String[] args) 方法的正确行为是什么?
此致
备案:
Do I have to register this implementation using procrun? But than there doesn't seem to be a point in implementing the interface as procrun can register any program as windows service.
是的,需要使用 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.Whosebug.questions.31556478.ServiceLauncher ^
--StartParams="@@PUT_ANY_START_ARGUMENTS_HERE@@" ^
--StartMethod=start ^
--StopMode=jvm ^
--StopClass=com.Whosebug.questions.31556478.ServiceLauncher ^
--StopMethod=stop
在此之后可以通过
启动服务
prunsrv //ES//MyTestSevice
And what would be the correct behavior of a static start(String[] args) method?
测试这两种变体,只有实现有效,它停留在启动方法中,没有产生额外的线程。这是一个可以使用上述 prunsrv 调用注册的启动器实现,看起来像这样(没有任何保证):
package com.Whosebug.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();
}
}
}
}
我没有找到任何关于如何将实现 org.apache.commons.daemon.Daemon
接口的 class 注册为 Windows 服务的真正好的示例(实际上我没有找到一个示例) .
我必须使用 procrun 注册这个实现吗?但是似乎没有实现接口的意义,因为 procrun 可以将任何程序注册为 windows 服务。
此外,procrun 页面上似乎有一个文档错误 (http://commons.apache.org/proper/commons-daemon/procrun.html):
--StartMethod
参数的描述指出:
Note: in jvm mode, the start method should not return until the stop method has been called.
但在 "Using Procrun in jvm mode" 部分的页面下方:
Note that the method handling service start should create and start a separate thread to carry out the processing, and then return. The start and stop methods are called from different threads.
我是不是读错了,还是有点矛盾??静态 start(String[] args) 方法的正确行为是什么?
此致
备案:
Do I have to register this implementation using procrun? But than there doesn't seem to be a point in implementing the interface as procrun can register any program as windows service.
是的,需要使用 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.Whosebug.questions.31556478.ServiceLauncher ^
--StartParams="@@PUT_ANY_START_ARGUMENTS_HERE@@" ^
--StartMethod=start ^
--StopMode=jvm ^
--StopClass=com.Whosebug.questions.31556478.ServiceLauncher ^
--StopMethod=stop
在此之后可以通过
启动服务prunsrv //ES//MyTestSevice
And what would be the correct behavior of a static start(String[] args) method?
测试这两种变体,只有实现有效,它停留在启动方法中,没有产生额外的线程。这是一个可以使用上述 prunsrv 调用注册的启动器实现,看起来像这样(没有任何保证):
package com.Whosebug.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();
}
}
}
}