首页 > 解决方案 > 错误“目录名称无效。” 使用 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);
        }
    }
}

'''

标签: javaapache-commonsprocrunapache-commons-daemon

解决方案


我想我找到了你的问题。

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 的父目录。

其他需要注意的事项:

  1. 我推荐使用 JDK,就像我在这个例子中使用的一样。当我像你一样使用 JRE 时,我得到一个不同的错误,关于无法找到主类。
  2. 我对“Program Files (x86)”使用快捷方式“Program~2”,因为某些 Windows 系统会阻塞路径中的空间。此外,引用它不应该是必需的。
  3. 我建议使用 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.

推荐阅读