Tuesday, April 9, 2013

Remote VisualVM

In my current project at work, I need to do some profiling on a Java app that runs on a server. Hooking it up to my local VisualVM (awesome tool, btw) was not immediately obvious to me, so here's the steps:

Prepare application on remote server

jstatd needs some security settings explained in [1]. Open vim, enter
grant codebase "file:${java.home}/../lib/tools.jar" {
  permission java.security.AllPermission;
and save as jstatd.all.policy.

Now start jstatd in the same directory, let in run in the background:
jstatd -J-Djava.security.policy=jstatd.all.policy &

Next, start the app (assuming $MY_APP is the main class) as described in [2]:
java \
 -Dcom.sun.management.jmxremote \
 -Dcom.sun.management.jmxremote.port=$JMX_PORT \
 -Dcom.sun.management.jmxremote.ssl=false \
 -Dcom.sun.management.jmxremote.authenticate=false \
 -Djava.rmi.server.hostname=$EXTERNAL_IP \
$JMX_PORT can be any available TCP port. $EXTERNAL_IP is the server's external IP address.

Make sure that the server's firewall allows incoming connections on both TCP 1099 (jstatd) and the port you chose as $JMX_PORT.

Connect VisualVM

Start VisualVM, double click on remote. Enter the server's external IP address:

Right-click on the new connection and add a JMX connection:
Enter $EXTERNAL_IP:$JMX_PORT from above, in my case
This should add a connection to the running app:
Double-click on it, start profiling, enjoy.