我正在尝试使用 Apache Common Daemons 创建 Windows 服务,但我无法使其按预期工作。
使用jvm 模式它总是返回错误 1067,没有进一步的解释。这是procrun日志:
[2020-11-18 15:56:20] [info] [11104] Apache Commons Daemon procrun (1.2.3.0 32-bit) started.
[2020-11-18 15:56:20] [info] [11104] Running Service 'ServiceTest14'...
[2020-11-18 15:56:20] [info] [14684] Starting service...
由于我需要 RXTX 并且我没有找到有效的 64 位实现(这是另一个故事),我被迫使用 32 位 jre:
C:\ServiceTest>java -version
java version "1.8.0_271"
Java(TM) SE Runtime Environment (build 1.8.0_271-b09)
Java HotSpot(TM) Client VM (build 25.271-b09, mixed mode, sharing)
所以我尝试了两个 procrun 版本:64 位和 32 位。没有区别。在这两种情况下,Windows 事件记录器都会报告没有有用信息的崩溃,至少对我来说不是。
[2020-11-18 16:52:53] [info] [20248] Apache Commons Daemon procrun (1.2.3.0 64-bit) started.
[2020-11-18 16:52:53] [info] [20248] Running Service 'ServiceTest14'...
[2020-11-18 16:52:53] [info] [20000] Starting service...
下面是 procrun 配置/设置脚本:
set SERVICE_NAME=ServiceTest14
set SERVICE_PATH=C:\ServiceTest
set JAR=ServiceTest2.jar
set SERVICE_CLASS=it.stikez.servicetest2.ServiceTest2
set PR_INSTALL=%SERVICE_PATH%\prunsrv.exe
sc stop %SERVICE_NAME%
sc delete %SERVICE_NAME%
REM Service log configuration
set PR_LOGPREFIX=%SERVICE_NAME%
set PR_STDOUTPUT=%SERVICE_PATH%\logs\stdout.txt
set PR_STDERROR=%SERVICE_PATH%\logs\stderr.txt
REM Path to java installation
set PR_CLASSPATH=.;%SERVICE_PATH%\%JAR%;%SERVICE_PATH%\lib\*
REM JVM configuration
set PR_JVMMS=256
set PR_JVMMX=1024
REM Install service
%SERVICE_PATH%\prunsrv.exe //IS//%SERVICE_NAME% ^
--Description="Test Service 7" ^
--Install=%PR_INSTALL% ^
--Startup=auto ^
--Jvm="C:\Program Files (x86)\Java\jre1.8.0_271\bin\client\jvm.dll" ^
--StartPath=%SERVICE_PATH% ^
--StartMode=jvm ^
--StartClass=%SERVICE_CLASS% ^
--StartMethod=main ^
--StartParams=start ^
--StopPath=%SERVICE_PATH% ^
--StopMode=jvm ^
--StopClass=%SERVICE_CLASS% ^
--StopMethod=main ^
--StopParams=stop ^
--LogPath=%SERVICE_PATH%\logs ^
--LogLevel=Trace
将jvm值设置为auto或一些无意义的乱码(比如说随机字符)也没有什么区别。但至少如果使用java模式(而不是jvm)它会启动。至少。Stop动作不起作用;我想它是在一个新的 jvm 会话中产生的,因为控制变量不受停止调用的影响。
下面是使用的 java 代码示例(由于我不需要 Linux 可移植性,因此直接取自 Apache 站点并进行了一些修改。
package it.stikez.servicetest2;
public class ServiceTest2 {
private static ServiceTest2 engineLauncherInstance = new ServiceTest2();
private static boolean stop = false;
public static void main(String[] args) {
String cmd = "start";
if (args.length > 0) {
cmd = args[0];
System.out.println("Service called with param: " + cmd);
}
if ("start".equals(cmd)) {
engineLauncherInstance.windowsStart();
} else {
engineLauncherInstance.windowsStop();
}
}
public void windowsStart() {
System.out.println("windowsStart called");
initialize();
while (!stop) {
System.out.println("nloop stop=" + stop);
// don't return until stopped
synchronized (this) {
try {
this.wait(60000); // wait 1 minute and check if stopped
} catch (InterruptedException ie) {
System.out.println("interrupted; stop=" + stop);
}
}
}
System.out.println("Service end");
}
public void windowsStop() {
System.out.println("windowsStop called (stop=" + stop + ")");
terminate();
synchronized (this) {
System.out.println("stop sync area");
// stop the start loop
this.notify();
}
System.out.println("stop call elaborated (stop=" + stop + ")");
}
private void initialize() {
}
public void terminate() {
stop = true;
}
}
我正在(拼命地)寻找一种让它在 jvm 模式下工作的方法,或者在用户想要时正确停止服务的任何其他魔术。