Setting this up will allow the use of JConsole and JVisualVM to be used for remote monitoring.

Benefits: First, running these tools remotely reduces the overall CPU and memory overhead on the remote box.  Second, you do not need physical access to the system to perform monitoring.

You should be sensitive to the following: security issues around allowing remote access to a JVM, and governance with IT departments to prevent too many connections to the remote JVM.  We will address the first issue in this post.  The second issue for now can only be addressed by the "honor" system and governance.

Setting this up on a local network (NO firewalls) is simple and straightforward.  We will first setup a configuration without authentication, then set it up with authentication enabled.

The following JVM parameters must be added to the command starting the JVM:

-Djava.rmi.server.hostname=<public ip address>

-Dcom.sun.management.jmxremote.local.only=false

-Dcom.sun.management.jmxremote.port=<port to use>

-Dcom.sun.management.jmxremote.ssl=false

-Dcom.sun.management.jmxremote.authenticate=false


The value for <public ip address> must be the hosts publicly available IP address.  If this is NOT added, the RMI server will bind to localhost, and no external hosts will be able to connect.

A command such as:

pubip=`ip addr show eth0 | grep "inet " | awk ' { print substr($2,1,length($2)-3) } '`

will set the variable ${pubip} to the hosts public IP address.

The value for <port to use> can be any port value greater than 1024 can be used, that is not already in use.

Now start your JVM (whether it be CQ, or whatever).  With this configuration, you can connect to the remote JVM with both of the following URL's:
<hostname>:<port to use>
service:jmx:rmi:///jndi/rmi://<hostname>:<port to use>/jmxrmi

I think filling in the first generates the second URL.  I have noticed that in some configurations used through a firewall the first URL did not work, and needed to be changed slightly.

Now to add security.  We won't add SSL in this post, but we will add a user and password to control who has remote JMX access.  It should be noted that there are some security issues with this, which can be found by doing a google search on the topic.

The next JVM parameter we must add is:
-Dcom.sun.management.jmxremote.password.file=<path>/jmxremote.password
and we must change:
-Dcom.sun.management.jmxremote.authenticate=false
to:
-Dcom.sun.management.jmxremote.authenticate=true.
Without this the JVM will dutifully IGNORE our password file completely.

Chances are what you will find is an existing jmxremote.password file that has everything commented out.  On an Ubuntu system, <path> will be: ${JAVA_HOME}/jre/bin/management/, and jmxremote.password will be a symbolic link to another location.  Simply edit this file and uncomment the following entries:

# monitorRole  QED

# controlRole   R&D


which should be the last 2 lines in the file.  These are your usernames and password.  Username on the left, password on the right.  I suggest leaving the username as-is, and only change the password.  If you do change the username, you will also need to modify the jmxremote.access.  Otherwise, what each user can do once a JMX session is created is already configured.  These roles are already setup to do exactly what they look like.  One can modify things, the other cannot.

Now, in order for the JVM to read the file, whatever user starts the JVM must be the only user with access to the file.  The following command should take care of that.  CD into the actual directory, not the directory containing the symbolic links.

sudo chown <user>.root ./jmxremote.password
sudo chmod go-rw ./jmxremote.password

Now fire up your JVM using the <user> account.

With JVisualVM, it remembers your connections.  The downside is that if you fire it up and the JVM's are not started, it will remove those connections.  There may be a way to get JVisualVM to remember these.

My next post will walk through setting this up with a CQ 5.5.0 JVM running on a Amazon AWS EBS instance.