The Core Technologies Blog

Professional Software for Windows Services / 24×7 Operation


Q&A: Why doesn’t Srvany Close my Application when I Stop the Service?

Q&A: Why doesn't Srvany close my Java application when I stop the service?
  We use Srvany to run our Java application as a service. It starts fine but when we stop the service our Java application does not close. We have to kill the java.exe process in Task Manager. That’s not supposed to happen, right? Is there a registry setting that we are missing that will shut down our application properly when we stop the service?

— Angela

Hi Angela.

As you probably know, Srvany is the original service wrapper. Its job is to accept commands from the Windows Service Control Manager (SCM) and take appropriate action on your java application. Simple, right?

Well, maybe not. Let’s examine what Microsoft’s service wrapper does when it receives the most important SCM commands — “start service” and “stop service”.

How Srvany handles the “Start Service” command

When you start your service — from the Services application, NET START, or SC START — the SCM immediately launches a fresh instance of srvany.exe and notifies it of the start request.

In response, Srvany:

  1. Informs the SCM that the service is starting.

  2. Starts the program configured to run as a service. The full command line is read from this registry value:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<Your Service>\Parameters\Application

If Srvany fails to start the application (which will happen if the application/path doesn’t exist), Srvany will:

  1. Inform the SCM that the service has stopped.

  2. Exit, ending the srvany.exe process.

On the other hand, if it successfully launches the application, Srvany will:

  1. Inform the SCM that the service is now running.

  2. Continue to run, listening for subsequent commands from the SCM.

Testing service start with Notepad

To confirm this behavior, we installed a new service (with Instsrv) and configured it to run the Windows Notepad text editor:

Notepad Windows Service installed with Srvany

We started the service.

With the help of Microsoft’s excellent Process Explorer, here is what the process tree looked like after a few seconds. As expected, there was a srvany.exe process that had spawned a notepad.exe child process:

Srvany running Notepad as a service

And Notepad was happily running in the background, on the isolated Session 0 desktop.

How Srvany handles the “Stop Service” command

When you attempt to stop your service — from the Services application, NET STOP, or SC STOP — the SCM immediately notifies the associated Srvany process of the stop request.

In response, Srvany will:

  1. Inform the SCM that the service is stopping.

  2. Close the process/application that it started.

  3. Inform the SCM that the service is stopped.

  4. Exit, ending the srvany.exe process.

When we stopped the Notepad service, Notepad.exe was terminated as expected.

But what happens when running a Java application/service?

Since stopping your Java application didn’t go smoothly, we decided to dig into that specific scenario.

We installed a new service and configured it to launch a Java JAR package:

Java/JAR Windows Service installed

When we started the service, we saw srvany.exe launch java.exe. No surprises there:

Srvany running Java as a service

And when we stopped the service, the java.exe process ended and Srvany exited — all good.

So how come it isn’t working for you?

What about a Java application started from a batch file?

After some head scratching, we realized something important. Many of our customers running Java as a service with AlwaysUp don’t run java directly. Instead, they start java via a batch file because it gives them the opportunity to set important environment variables in advance. Could that be an issue?

To answer that question, we created a simple batch file that launched java and installed a new service to run the batch file:

Batch File Windows Service installed

We started the service. Srvany launched the batch file (cmd.exe), which in turn launched Java — all as intended:

Srvany running the batch file (and Java) as a service

However, when tried to stop the service, something unexpected happened. The service stopped and srvany.exe and cmd.exe closed, but java.exe did not exit! The Java process remained running, even after the service had transitioned to the stopped state. It was exactly as you described.

So from these tests, it seems that Srvany will terminate the process it launched (i.e. its direct child process) but will not terminate any descendant processes.

Do you think this is what you are experiencing? If so, please read on for a couple of potential solutions.

Solution #1: Run the Java executable directly from Srvany

Instead of starting Java from a batch file, let Srvany run your Java.exe command line itself. As we have shown above, Srvany is able to terminate Java when it launches it directly.

However, this option may be impractical if your batch file performs lots of setup. But if the batch file focuses on setting environment variables (e.g. CLASSPATH), you can get around that by:

  1. Permanently setting the environment variables in a specific user account, and

  2. Running Java in that account (by specifying the user’s details on the service’s Log On tab).

Solution #2: Install your Java application as a service with AlwaysUp instead of Srvany

Alternatively, if this is a professional setting and a commercial option is acceptable, you can replace Srvany with our AlwaysUp utility.

When you stop a service created by AlwaysUp, all descendant processes are terminated. That is, AlwaysUp will close cmd.exe, java.exe — and any other processes that your Java application spawns. You will never have a situation where your service is stopped but some processes remain alive.

Please review the benefits to using AlwaysUp instead of Srvany to see if you should make the switch.

Best of luck managing your Java application!

Posted in Srvany | Tagged , , , , , | Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *