我刚刚继承了一个java应用程序,需要在XP和vista上作为服务安装。我已经8年没有使用任何形式的windows了,我从来没有创建过服务,更不用说从java应用程序(我已经为应用程序准备了一个jar和一个依赖jar - log4j)。使其作为服务运行所必需的魔力是什么?我已经得到了源代码,所以代码修改(尽管最好避免)是可能的。


当前回答

我以前用过JavaService,而且很成功。它已经有几年没有更新了,但当我使用它的时候,它非常坚固。

其他回答

我不喜欢Java服务包装器的授权。我使用ActiveState Perl编写了一个完成这项工作的服务。

我想过用c#写一个服务,但是我的时间太紧了。

在过去几年里,我一直在使用jar2exe在Windows上运行我们的Java应用程序作为服务。它提供了一个选项来创建一个exe文件,可以作为Windows服务安装。

我以前用过JavaService,而且很成功。它已经有几年没有更新了,但当我使用它的时候,它非常坚固。

通过结合使用外部内存和连接器API(从JDK16开始预览)与OpenJDK jextract项目来处理Windows服务的回调,然后使用jpackage来生成一个Windows EXE,然后可以注册为Windows服务,这是可能在100% Java代码中实现Windows服务。

请看这个例子,它概述了实现Windows服务所需的工作。所有Windows服务EXE必须为主入口点ServiceMain和服务控制处理程序提供回调,并在Advapi.DLL中使用API调用StartServiceCtrlDispatcherW, RegisterServiceCtrlHandlerExW和SetServiceStatus。

在具有外部内存结构的Java中,上述回调的流程是:

main()
    Must register ServiceMain using StartServiceCtrlDispatcherW
    Above call blocks until ServiceMain exits
        
void ServiceMain(int dwNumServicesArgs, MemoryAddress lpServiceArgVectors)
    Must register SvcCtrlHandler using RegisterServiceCtrlHandlerExW
    Use SetServiceStatus(SERVICE_START_PENDING)
    Initialise app
    Use SetServiceStatus(SERVICE_RUNNING)
    wait for app shutdown notification
    Use SetServiceStatus(SERVICE_STOPPED)

int SvcCtrlHandler(int dwControl, int dwEventType, MemoryAddress lpEventData, MemoryAddress lpContext)
    Must respond to service control events and report back using SetServiceStatus
    On receiving SERVICE_CONTROL_STOP reports SetServiceStatus(SERVICE_STOP_PENDING)
        then set app shutdown notification

一旦完成Java应用程序,jpackage可以创建运行时+EXE,然后可以安装和注册为Windows服务。以管理员身份运行(=后面的空格很重要):

 sc create YourJavaServiceName type= own binpath= "c:\Program Files\Your Release Dir\yourjavaservice.exe"

另一种选择是WinRun4J。这是一个可配置的java启动器,可作为windows服务主机(32位和64位版本)。它是开源的,使用上没有限制。

(完全披露:我参与了这个项目)。