Reputation: 181
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:
A couple of final points:
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?
Upvotes: 18
Views: 9851
Reputation: 615
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
[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
Upvotes: 12
Reputation: 7069
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
Upvotes: 2
Reputation: 1
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.
Upvotes: 0
Reputation: 3499
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
Upvotes: 8