LendKey

Sunday, August 15, 2010

How to monitor Java app started as Windows Service


If you have a Java server running as Windows Service, such as Tomcat, JBoss, etc., it's not possible to run JConsole or JVisualVM to monitor those JVMs, because Windows doesn't allow those apps to see JVM started as Windows Service.

There're two ways I fund over the internet:
1. You can use Sysinternals PsExec.exe to accomplish this.
psexec.exe -i -s c:\visualvm\bin\visualvm.exe


2. Use interactive Windows Service:

1. Install a service using sc.exe - that will open a command prompt under local service account by executing this on cmd window sc create debugservice binpath= "cmd /K start" type= own type= interact 2. sc start debugservice [on a remote desktop session, this service has to be started only in console session for the command prompt window to pop up] will print message that [SC] StartService FAILED 1053: but will start a command prompt under local system account. 3. now navigate to %JAVA_HOME%/bin on the command prompt that got opened and type in jmap -dump:format=b,file=D:\temp\test.hprof  this will dump the heap to D:\temp folder. Be careful dumping heap on a live system as it will lock up the system for the duration of heap dump. 4. similarly jconsole can be started using that command prompt and connecting to the pid of the tomcat. Technical explanation: a. as tomcat service is installed under local system account, jconsole / jmap cannot connect to the service when these are started under the windows logged in user. b. So the command prompt interactive service is installed as a local system service and when that service is started, it opens the command prompt under local system account. c. And hence any process started from that command prompt will be started under local system account and hence be able to access any local system services.

2 comments:

Gili Nachum said...

LI, I'm not sure that I got the problem? is it about not being able to hook up to a Java process if it is running as a windows service?

If so:
Isn't there a process behind each windows service?
And if so, I know that JConsole can receive the process ID (PID) as a command line parameter.
Won't that work?

Li Ma said...

Gili,

I tried that, didn't work.
Let's say my Java process id is 3728.
If I run JConsole as normal user:
jconsole 3728
I will get err msg like:
Invalid process id:3728

Even I start a DOS BOX as administrator, and start jconsole from there, I will get the same error msg.

Li