Apache Commons Daemon注册jpackage生成的exe为Windows服务后停止报错
问题分析与解决方案
你的问题核心是使用StartMode=exe模式注册服务时,Apache Commons Daemon无法向jpackage生成的exe传递优雅停止信号,只能强制终止进程,导致关闭钩子不触发,同时Windows服务管理因为进程未正常退出而报错。
解决步骤
1. 替换启动模式为JVM原生支持
procrun对Java服务的jvm模式有原生的信号传递支持,能正确触发Java的关闭钩子,所以需要把StartMode=exe改为StartMode=jvm,同时调整相关参数。
2. 修改服务注册命令
先卸载原有服务(如果已注册):
prunsrv.exe //DS/my-service
然后使用以下命令重新注册:
prunsrv.exe //IS/my-service ^ --Description="My Client" ^ --StartPath="E:\clients\my-client" ^ --StartMode=jvm ^ --Classpath="E:\clients\my-client\my-client.jar" ^ --StartClass=com.yourpackage.MainClass ^ --Startup=auto ^ --Jvm=auto ^ --LogPath="E:\clients\my-client\logs" ^ --StopMode=jvm ^ --StopClass=com.yourpackage.MainClass ^ --StopMethod=stop ^ --StopTimeout=30000
参数说明
--Classpath:指定你的应用jar包路径(jpackage生成的目录里会有对应的jar,比如app子目录下的文件)--StartClass:你的Java主类全限定名--StopMode=jvm:告诉procrun通过JVM信号触发优雅停止--StopClass:通常和启动类一致,若有单独的停止逻辑类可修改--StopMethod:指定触发停止的方法(默认是stop,如果是Spring Boot应用可改为close,需确保该方法为静态无参方法)--StopTimeout:给应用预留的关闭缓冲时间(单位毫秒,这里设为30秒,可根据实际业务调整)
原模式失效原因
jpackage生成的exe是Java应用的包装器,运行后会启动独立的JVM进程。当用StartMode=exe时,procrun只能监控exe进程,停止时会直接强制杀死该进程,无法将停止信号传递给内部的JVM,导致Java应用的关闭钩子无法执行,进程异常退出,从而触发Windows服务的错误提示。
验证方式
重新注册服务后,启动服务再尝试停止:
- 检查Windows服务管理器是否能正常停止服务,无报错弹窗
- 查看应用日志,确认关闭钩子的日志已正常输出
内容的提问来源于stack exchange,提问作者Lesrac
相关产品推荐
相关产品推荐

