java - 错误“目录名称无效。” 使用 apache daemon windows service 执行 jar 时
问题描述
我正在尝试将一个简单的 java jar 作为 Windows 服务运行。创建服务并尝试启动它后,我收到以下错误:
ServiceStart 返回 5。目录名无效。
完整日志:
[2019-09-27 14:24:46] [debug] ( prunsrv.c:1441) [14148] Inside ServiceMain...
[2019-09-27 14:24:46] [debug] ( prunsrv.c:904 ) [14148] reportServiceStatusE: dwCurrentState = 2, dwWin32ExitCode = 0, dwWaitHint = 3000, dwServiceSpecificExitCode = 0.
[2019-09-27 14:24:46] [info] ( prunsrv.c:1196) [14148] Starting service...
[2019-09-27 14:24:46] [debug] (rprocess.c:519 ) [14148] Apache Commons Daemon apxProcessExecute()
[2019-09-27 14:24:46] [debug] (rprocess.c:258 ) [14148] Apache Commons Daemon procrun __apxProcCreateChildPipes()
[2019-09-27 14:24:46] [debug] (rprocess.c:535 ) [14148] Apache Commons Daemon AplZeroMemory()
[2019-09-27 14:24:46] [debug] (rprocess.c:550 ) [14148] Apache Commons Daemon GetEnvironmentStringsW()
[2019-09-27 14:24:46] [debug] (rprocess.c:572 ) [14148] Apache Commons Daemon CreateProcessW()
[2019-09-27 14:24:46] [debug] (rprocess.c:616 ) [14148] Apache Commons Daemon apxProcessExecute() returning FALSE
[2019-09-27 14:24:46] [error] ( prunsrv.c:1317) [14148] Failed to execute process.
[2019-09-27 14:24:46] [error] ( prunsrv.c:1317) [14148] The directory name is invalid.
[2019-09-27 14:24:46] [error] ( prunsrv.c:1604) [14148] ServiceStart returned 5.
[2019-09-27 14:24:46] [error] ( prunsrv.c:1604) [14148] The directory name is invalid.
[2019-09-27 14:24:46] [debug] ( prunsrv.c:904 ) [14148] reportServiceStatusE: dwCurrentState = 1, dwWin32ExitCode = 1066, dwWaitHint = 0, dwServiceSpecificExitCode = 5.
[2019-09-27 14:24:46] [info] ( prunsrv.c:1670) [ 7252] Run service finished.
[2019-09-27 14:24:46] [info] ( prunsrv.c:1839) [ 7252] Apache Commons Daemon procrun finished.
即使我以管理员身份运行命令,Windows 事件查看器也会显示以下内容:
The DaemonService service terminated with the following service-specific error:
Access is denied.
用于创建服务的命令:
开始.bat
set JVM_DLL="C:\Program Files (x86)\Java\jre1.8.0_211\bin\client\jvm.dll"
set JAVA_H="C:\Program Files (x86)\Java\jre1.8.0_211\bin"
prunsrv.exe //IS//DaemonService --Description="Agent Demon Service" --Classpath="D:\procrun\daemon.jar" --StartMode=java --StartClass=com.oracle.TestDaemon --StartParams=start --StdOutput=auto --StdError=auto --JavaHome=%JAVA_H% --StartMethod=start --Jvm=%JVM_DLL% --StopMode=java --StopMethod=stop --StopParams=stop --StopClass=com.oracle.TestDaemon --StdOutput=D:\procrun\logs\stdOut.log --StdError=D:\procrun\logs\stdErr.log --LogLevel=Debug --LogPath=D:\procrun\logs --LogPrefix=com-daemon
我在 daemon.jar 中有一个非常简单的代码,如下所示,如果使用 java -jar 执行,jar 可以工作:
package com.oracle;
public class TestDaemon {
private static boolean stop = false;
public static void start(String[] args) {
System.out.println("start");
try{
Thread.sleep(5000);
}catch (InterruptedException e) {
e.printStackTrace();
}
while (!stop) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void stop(String[] args) {
System.out.println("stop");
stop = true;
System.exit(0);
}
public static void main(String[] args) {
System.out.println("Executing main");
if(args== null || args.length == 0){
System.out.println("Args is null");
args = new String[1];
args[0] = "start";
}
if ("start".equals(args[0])) {
start(args);
} else if ("stop".equals(args[0])) {
stop(args);
}
}
}
'''
解决方案
我想我找到了你的问题。
set JAVA_H="C:\Program Files (x86)\Java\jre1.8.0_211\bin"
应该
set JAVA_H=C:\Progra~2\Java\jdk1.8.0_222
JAVA_HOME 不应该指向bin 目录;相反,它应该指向 bin 的父目录。
其他需要注意的事项:
- 我推荐使用 JDK,就像我在这个例子中使用的一样。当我像你一样使用 JRE 时,我得到一个不同的错误,关于无法找到主类。
- 我对“Program Files (x86)”使用快捷方式“Program~2”,因为某些 Windows 系统会阻塞路径中的空间。此外,引用它不应该是必需的。
- 我建议使用 64 位 Java 和 64 位 prunsrv.exe,因为如果您阅读日志,您会看到,在某些情况下(但不是全部)。所以我使用 64 位版本的 Apache Daemon。
启动脚本
setlocal
set JVM_DLL=C:\Progra~2\Java\jdk1.8.0_222\jre\bin\server\jvm.dll
set JAVA_H=C:\Progra~2\Java\jdk1.8.0_222
prunsrv.exe //IS//testDaemon --Description="Agent Demon Service" --Classpath="untitled-1.0-SNAPSHOT.jar" --StartMode=java --StartClass=com.oracle.TestDaemon --StartParams=start --StdOutput=auto --StdError=auto --JavaHome=%JAVA_H% --StartMethod=start --Jvm=%JVM_DLL% --StopMode=java --StopMethod=stop --StopParams=stop --StopClass=com.oracle.TestDaemon --StdOutput=C:\test\daemon\stdOut.log --StdError=C:\test\daemon\err.log --LogLevel=Debug --LogPath=C:\test\daemon\logs --LogPrefix=com-daemon
标准输出日志
2020-02-05 15:39:14 Apache Commons Daemon procrun stdout initialized.
Error occurred during initialization of VM
Could not reserve enough space for 716800KB object heap
安装和启动的完整日志文件:
[2020-02-05 15:38:55] [debug] ( prunsrv.c:1754) [28424] Apache Commons Daemon procrun log initialized.
[2020-02-05 15:38:55] [info] ( prunsrv.c:1758) [28424] Apache Commons Daemon procrun (1.2.1.0 32-bit) started.
[2020-02-05 15:38:55] [debug] ( prunsrv.c:615 ) [28424] Installing service...
[2020-02-05 15:38:55] [info] ( prunsrv.c:654 ) [28424] Installing service 'testDaemon' name ''.
[2020-02-05 15:38:55] [debug] ( prunsrv.c:670 ) [28424] Setting service description 'Agent Demon Service'.
[2020-02-05 15:38:55] [info] ( prunsrv.c:688 ) [28424] Service 'testDaemon' installed.
[2020-02-05 15:38:55] [info] ( prunsrv.c:1839) [28424] Apache Commons Daemon procrun finished.
[2020-02-05 15:39:14] [debug] ( prunsrv.c:1754) [37856] Apache Commons Daemon procrun log initialized.
[2020-02-05 15:39:14] [info] ( prunsrv.c:1758) [37856] Apache Commons Daemon procrun (1.2.1.0 32-bit) started.
[2020-02-05 15:39:14] [info] ( prunsrv.c:1668) [37856] Running Service 'testDaemon'...
[2020-02-05 15:39:14] [debug] ( prunsrv.c:1441) [24212] Inside ServiceMain...
[2020-02-05 15:39:14] [debug] ( prunsrv.c:904 ) [24212] reportServiceStatusE: dwCurrentState = 2, dwWin32ExitCode = 0, dwWaitHint = 3000, dwServiceSpecificExitCode = 0.
[2020-02-05 15:39:14] [info] ( prunsrv.c:1196) [24212] Starting service...
[2020-02-05 15:39:14] [debug] (rprocess.c:519 ) [24212] Apache Commons Daemon apxProcessExecute()
[2020-02-05 15:39:14] [debug] (rprocess.c:258 ) [24212] Apache Commons Daemon procrun __apxProcCreateChildPipes()
[2020-02-05 15:39:14] [debug] (rprocess.c:535 ) [24212] Apache Commons Daemon AplZeroMemory()
[2020-02-05 15:39:14] [debug] (rprocess.c:550 ) [24212] Apache Commons Daemon GetEnvironmentStringsW()
[2020-02-05 15:39:14] [debug] (rprocess.c:572 ) [24212] Apache Commons Daemon CreateProcessW()
[2020-02-05 15:39:14] [debug] (rprocess.c:594 ) [24212] Apache Commons Daemon CreateThread()
[2020-02-05 15:39:14] [debug] (rprocess.c:597 ) [24212] Apache Commons Daemon CreateThread()
[2020-02-05 15:39:14] [debug] (rprocess.c:600 ) [24212] Apache Commons Daemon ResumeThread()
[2020-02-05 15:39:14] [debug] (rprocess.c:602 ) [24212] Apache Commons Daemon CreateThread()
[2020-02-05 15:39:14] [debug] (rprocess.c:608 ) [24212] Apache Commons Daemon apxProcessExecute() returning TRUE
[2020-02-05 15:39:14] [info] ( prunsrv.c:1352) [24212] Service started in 30 milliseconds.
[2020-02-05 15:39:14] [debug] ( prunsrv.c:904 ) [24212] reportServiceStatusE: dwCurrentState = 4, dwWin32ExitCode = 0, dwWaitHint = 0, dwServiceSpecificExitCode = 0.
[2020-02-05 15:39:14] [debug] ( prunsrv.c:1596) [24212] Waiting for worker to finish...
[2020-02-05 15:39:15] [debug] (rprocess.c:122 ) [35084] Child process exit code 1
[2020-02-05 15:39:15] [debug] ( prunsrv.c:1601) [24212] Worker finished.
[2020-02-05 15:39:15] [debug] ( prunsrv.c:1628) [24212] Waiting for all threads to exit.
[2020-02-05 15:39:15] [debug] ( prunsrv.c:904 ) [24212] reportServiceStatusE: dwCurrentState = 3, dwWin32ExitCode = 0, dwWaitHint = 0, dwServiceSpecificExitCode = 0.
[2020-02-05 15:39:15] [debug] ( prunsrv.c:1632) [24212] JVM destroyed.
[2020-02-05 15:39:15] [debug] ( prunsrv.c:904 ) [24212] reportServiceStatusE: dwCurrentState = 1, dwWin32ExitCode = 1066, dwWaitHint = 0, dwServiceSpecificExitCode = 1.
[2020-02-05 15:39:15] [info] ( prunsrv.c:1670) [37856] Run service finished.
[2020-02-05 15:39:15] [info] ( prunsrv.c:1839) [37856] Apache Commons Daemon procrun finished.
推荐阅读
- ios - iOS - DCAppAttestService 生成证明对象的限制
- javascript - 如何在输入之前限制用户输入点但允许之后
- angular - Angular 使用 Akita 商店 ngOnInit 在首次加载时不起作用
- react-native - React Native - Sentry.captureException 不起作用
- r - 使用 ODBC 包将数据从 SQL Server 保存或读取到 R
- python - Python3 - “subprocess.call()”函数的问题
- r - 添加重复序列号的列
- python - 如果满足列中值的范围,则从多个文件中提取整行数据
- python - 在 Django 项目中删除以前发送的通知
- prolog - Prolog 真的基于封闭世界假设吗?