18

I'm trying to profile a Servlet running in Apache Tomcat (7.0.34) as a service on Windows 7 (64 bit) using JVisualVM (JDK 1.7.0 - 06, 64 bit) running locally.

Initially I had the problem of Tomcat not showing in the list of local applications due to the differing "java.io.tmp" property bug/feature, but worked around it as advised in several posts in this forum.

However although the Tomcat process now shows in the list of local applications as "Local Application", when I open the process there are no tabs for Monitor, Threads, Sampler or Profile - only the Overview tab for which the JVM arguments and Sytem Properties sub-tabs show the dreaded "not supported for this jvm" message.

I have double checked the following items:

  • that both Tomcat and JVisualVM are running the same version of Java by looking at the JVM properties in JVisualVM (using a JMX connection for Tomcat)
  • that both Tomcat and JVisualVM have the same "java.io.tmp" path by looking at the System Properties in JVisualVM (again using a JMX connection for Tomcat) AND looking at the actual TMP/TEMP directory and confirming that the PID files for both exist
  • that the file system is NTFS
  • that the Windows user does not have an underscore in the name (Note: the user does have a period in the name as we are using network logins of the form "firstname.lastname", however I have no problems viewing other Java applications in JVisualVM so don't think this is an issue)
  • that both Tomcat and JVisualVM are being executed as the same Windows user by looking at the processes in Task Manager

A couple of final points:

  • I need to Profile the Servlet so using JMX is not sufficient
  • I was able to profile on a Windows XP machine (Java 7, Tomcat 7 as a service), so would appear to be a Windows 7 / 64 bit thing?

If anyone has had and solved this issue obviously the solution would be much appreciated. However would be useful to just know if other people are running the same configuration - Windows 7 64 bit, Java 7 64 bit, Tomcat 7 running as a service - successfully.

Update: Instead of running as a service, I ran Tomcat using the batch file and all worked perfectly: what is it about running as a service?

buzz3791
  • 1,683
  • 2
  • 20
  • 38
Mr Anderson
  • 181
  • 1
  • 4
  • Just so you know you're not crazy, I've had the same issue with other servlet containers. I usually fire up Sysinternals Process Explorer, look at the "command line" column (the default Win process explorer is capped at 255 chars), execute that from a command prompt, and attach VisualVM. – Justin Garrick Feb 14 '13 at 14:29
  • What Windows user is your Tomcat service running as? That can make all the difference. Try running VisualVM as the exact same user the Tomcat service runs as. – JoshDM Feb 14 '13 at 21:11

4 Answers4

11

As already hinted in my previous comment. I guess the simple answer is it's not possible. In order to realize the communication between jconsole/jvisualvm and the to be monitored process Java uses memory mapped files. In the end it boils down to a certain Windows API call that fails due to the "Windows Service Hardening" [1] feature added in Windows Vista and which, of course, also exists in Windows 7 and later versions.

The call which fails is to the function OpenFileMapping as can be seen in perfMemory_windows.cpp line 1402 [2]. During my experiments the method is called with an argument of the form "hsperfdata_[username]_[process id]". As further detailed in Microsofts explanation of the differences introduced by the service hardening (see [3]) communication won't work if no name prefix is used: "If a user application [...] synchronizes with the service by creating or opening objects with the Local\ prefix (or no prefix, which defaults to Local), the application no longer works as expected."

If someone wants to take a look himself. You can use the Logger tool [4] included with the Windows debugging tools to trace API calls.

Also the Sysinternals Process Explorer is very handy as it shows the full names used for memory mapped files via its "Find Handle or DLL..." function. Just search for handles containing "hsperf".

As a side note: The workaround to delete or otherwise mess with the temporary directory which contains the hsperf data boils down to the fact that the case of the username used by the to be monitored process and the monitoring process need to be consistent. But instead of changing the temporary directory you can also easily change the USERNAME environment variable used by the monitoring process. You can also see how it is being used in in perfMemory_windows.cpp line 272 [2].

[1] http://technet.microsoft.com/en-us/library/cc507844.aspx#EHF

[2] http://hg.openjdk.java.net/jdk7/hotspot-rt/hotspot/file/5dce25362b8a/src/os/windows/vm/perfMemory_windows.cpp

[3] http://msdn.microsoft.com/en-us/windows/hardware/gg463353.aspx

[4] http://msdn.microsoft.com/en-us/library/windows/hardware/ff560123(v=vs.85).aspx

Christian K.
  • 605
  • 8
  • 10
8

You nearly made it "Instead of running as a service, I ran Tomcat using the batch file and all worked perfectly: what is it about running as a service" Now the only step left was to run JVisualVM as service :)

Refer this

https://blogs.oracle.com/nbprofiler/entry/monitoring_java_processes_running_as

Since only Java processes running under the same user as VisualVM can be profiled, the only way to profile Windows service (which is by default running under the System account) is to start the VisualVM itself as a Windows service. Note that this approach doesn't work on Windows Vista due to security restrictions which by default prevent the services to display any UI.

Another option is to run to Run CMD.EXE as Local System , Refer below.

http://vicevoice.blogspot.in/2009/09/vaas-visualvm-as-service.html

Manish Singh
  • 3,463
  • 22
  • 21
  • 1
    (& JoshDM) - Thx for the response(s) however I did make sure the service was running as the user I was logging in as (see the last dot point of the "double checked items" in original post ;-). Also note that I was able to get things working on XP. One point I didn't mention in the post was that I also tried running VisualVM as an administrator - no joy there either. However, I will try running VisualVM as a service and let you know. Thx again – Mr Anderson Feb 25 '13 at 04:27
  • It seems that running cmd as local system (or at least as described in the link in that link!) doesnt work on windows 8. The original article is from 2004 and I suppose things have changed since then. It looks similar except I get a warning about type= interact being deprecated – JonnyRaa Jul 25 '14 at 12:17
  • run VIsualVM as same account as the service makes it appear in VisualVM but not data is shown. `psexec -i -s cmd.exe' followed by `C:\tools\visualvm_214\bin\visualvm.exe --jdkhome C:\myJava\jdk\` – Tilo Sep 16 '22 at 01:02
2

Can't you just connect over the network, i.e start the JVM with

 java 
  -Dcom.sun.management.jmxremote
  -Dcom.sun.management.jmxremote.port=1234 
  -Dcom.sun.management.jmxremote.local.only=false 
  -Dcom.sun.management.jmxremote.authenticate=false 
  -Dcom.sun.management.jmxremote.ssl=false 
  -jar my.jar`

and create a network connection in the tool to localhost:1234

Kire Haglin
  • 6,569
  • 22
  • 27
0

I'd also be curious if anyone has a solution on Windows 7. As was noted the trick of running VisualVM as a service doesn't work on Vista and I'm assuming the same security features are preventing it from working on Win 7.

The only solution I have is to set up your app server (Tomcat) as a service so that if the server is rebooted it will come up and be available. Then manually stop the service and start your app server (Tomcat) from a command line and connect with VisualVM. Then you've got nice monitoring as long as the server isn't rebooted.

Mithel
  • 1
  • 1
  • Just as an additional remark why usage of jconsole/jvisualvm together with windows services got harder with Windows Vista and later. This is due to a new "feature" added called "Windows Service Hardening" [1]. I assume that is has something to do with the session isolation mechanisms since jconsole/jvisualvm rely on local IPC mechamisms (shared memory mapped file or named pipe) which need to cross the session boundaries. [1] http://technet.microsoft.com/en-us/library/cc507844.aspx#EHF – Christian K. Jan 27 '14 at 13:01