views:

742

answers:

4

I frequently showcase the jhat, jps, and jstack tool set to developers on Linux and Mac. However, a developer recently indicated that these are unusable in Windows if the Java app in question is running as a Windows Service.

A Sun-filed bug says something very similar, but was closed due to inactivity.

I have tested this out for myself, and indeed it appears true, though I can hardly believe it. Here is the setup:

  1. Tomcat or similar running as a Windows service with the "Log On As" == "Local System"
  2. A user with Admin privileges logged in to the same Windows machine.
  3. Admin opens Windows Task Manager, can see java.exe running
  4. Admin opens console, types "jps", gets back a list of processes that does not include Tomcat's java service process.
  5. As a brute force attempt, get the PID of tomcat as a service from Windows Task Manager. Type jstack < pid >. Get a reply: < pid > no such process

This appears reproducible under Windows XP, Windows 2003 Server, and Windows 7. Java versions 1.5 and 1.6 yield the same outcome.

Is there a way from the terminal, even though logged in as Admin, to "sudo up" to get JPS and the other tools to see the java service?

+1  A: 

You only get those processes that "belong" to you - same user id.

Can you connect to it with jvisualvm?

Thorbjørn Ravn Andersen
Can't get to the processes with jvisualvm either. Apparently jps and jvisualvm use the identical underlying lib/api for their interrogation (jvmstat)
Matthew McCullough
+3  A: 

I've had luck debugging processes run by the SYSTEM user by running this from a command prompt:

c:> time/t
11:18 AM
c:> at 11:19 /interactive cmd.exe
Added a new job with job ID = 1

Use a time 1 minute in the future. When the "at" job runs a windows command prompt will open running as the user SYSTEM. From there you should be able to see the java processes.

If the service is running as a local user (check the details from "mmc %windir%\system32\SERVICES.MSC" by double clicking on the service and selecting the "Log On" tab) you can do the same thing using "runas":

runas /user:USERNAME cmd.exe
Devon_C_Miller
+1 Wicked, I love it :)
Thorbjørn Ravn Andersen
See this related question: http://stackoverflow.com/questions/77528/how-do-you-run-cmd-exe-under-the-local-system-account
ripper234
I know see the services in jconsole, but can't connect to them (they are grayed out). When I manually try to connect to the port, I can't. CurrPorts shows the correct port is definitely listened to by the JVM.
ripper234
Note: this approach will not work under Vista or Win7 unless you disable the UAC http://www.howtogeek.com/howto/windows-vista/4-ways-to-make-uac-less-annoying-on-windows-vista/
Devon_C_Miller
I haven't tried it yet, but here's an article on writing a service that opens a SYSTEM console: http://www.codeproject.com/KB/vista-security/SubvertingVistaUAC.aspx
Devon_C_Miller
+1  A: 

I've only found a suggest to run visuamvm (or other tools) as windows service: Monitoring Java Processes Running As a Windows Service

Perhaps someone else knows a better solution.

marabol
+1  A: 

To get the utilities to run, you can connect to the Console session using "mstsc /admin" using a login account (not sure exact permissions it needs to have, mine was in the Administrators group) and use the Sysinternals psexec tool to run as system. Here is an example of using jstack.exe:

psexec -s "%JAVA_HOME%\bin\jstack.exe" PID >stack.txt
Where PID is the process ID of your process. You may also have to substitute the actual path to your JDK depending upon your specific environment.

Also, the TEMP directory must be set correctly or once again the tools will not work.

Rob Tanzola
this works very fine!
marabol