Lord Farquaad
Lord Farquaad

Reputation: 707

How does a java Windows service "know" it has finished initializing?

TL;DR: I have a Windows service written in Java, jarred, and installed with Procrun. I am starting it with W32Service.startService(). When does the service tell Windows it has started?


I'm working with windows services written in Java. I've been jarring and using Procrun to install them, and JNA to work with them (in particular, com.sun.jna.platform.win32.W32Service).

I would like to understand in the exact behavior of the W32Service object's waitForNonPendingState() method (which is the X to my Y: understand the exact behavior of startService()).

waitForNonPendingState() is actually very straightforward: it polls the status of the service until it's either in a non-pending state or a timeout occurs. How a service transitions to a non-pending state isn't so straightforward though.

Microsoft's Service State Transitions page says:

The initial state of a service is SERVICE_STOPPED. When the SCM starts the service, it sets the service state to SERVICE_START_PENDING and calls the service's ServiceMain function. The service then completes its initialization using one of the techniques described in Service ServiceMain Function. After the service completes its initialization and is ready to start receiving control requests, the service calls SetServiceStatus to report SERVICE_RUNNING...

But that doesn't really shed any light on how the service does this. The ServiceMain remarks also just say "The Service Control Manager (SCM) waits until the service reports a status of SERVICE_RUNNING."; that's pretty much as specific as I can find.

Which brings me to my question: How does a java Windows service "know" it has finished initializing?

In other words, if I have an installed service with a main() method:

public class SampleService {

    public static void main(String[] args) {
        if ("start".equals(args[0]))
            new SampleService();
    }

    public SampleService() {
        // do a whole bunch of stuff
    }
}

and I call:

W32Service service = serviceManager.openService("SampleService", 
                                                Winsvc.SC_MANAGER_ALL_ACCESS);
service.startService();

At what point does my SampleService tell Windows it has initialized? Through experimentation, I can see that if there's a runtime exception during construction, the service's status is never SERVICE_RUNNING, so there's something in that process which sets that status. But some of my constructors wait on queues or enter spin loops and they do set the SERVICE_RUNNING status, so I can't tell where this status is set. W32Service's documentation is less than useless on this.

Upvotes: 1

Views: 268

Answers (1)

amritanshu
amritanshu

Reputation: 797

Your service is not really exposed as regular service it relies on Procrun as soon as the JVM is spawned as part of the process or separately the service state is set to running. In prunsrv.c which has the service container code for procrun you can check how serviceStart() is called and what happens on success.

Upvotes: 0

Related Questions