While working on our Tomcat servers, I’m often astonished at how much I didn’t know that would make my life a lot easier.  Case in point, when we discovered the need to remove the Tomcat manager from all our servers, but still needed access to the information (such as…is this Tomcat application up?  Are there active sessions in the application? etc…), we weren’t sure what to do.  One of our biggest problems is we were required to remove the Tomcat manager as it is a PCI compliance issue and makes it very easy for an attacker to shutdown and modify your site.  From on high comes VisualVM to save the day!

VisualVM is great for showing CPU, threads, memory, PermGen space, and the like.  However, it has a plugin called MBeans that gives you a ton of information about your system.  To allow you to gather your data and yet keep the system secure, you will need to setup jmx.  JMX is a protocol that creates a bi-directional tunnel between a remote session and Tomcat’s JVM.  To set it up, you will need to add some environment variables to your Java startup and a line in your server.xml, like below:

Environment file additions:

-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true -Djava.rmi.server.hostname={Enter IP Here} -Dcom.sun.management.jmxremote.password.file=/usr/share/tomcat/conf/jmxremote.password -Dcom.sun.management.jmxremote.access.file=/usr/share/tomcat/conf/jmxremote.access -Dcom.sun.management.jmxremote=true

Server.xml File addtions:

<Listener className=”org.apache.catalina.mbeans.JmxRemoteLifecycleListener” rmiRegistryPortPlatform=”9055″ rmiServerPortPlatform=”9056″ />

Let me go into a little detail about where to add those.  In the environments I build, I try to have a separate startup parameters file so that it is always the same on every Tomcat cluster I create.  If you don’t have a separate file, that’s ok.  You would simply add it to the init.d/tomcat startup file or Catalina.sh or Startup.sh if you are using those.  You can simply add the above additions to the end of the list and save.

For the server.xml file, you simply need to make it the last line of listeners under
<Server port=”8005″ shutdown=”SHUTDOWN”>
before you add any global JNDI resources.

The next step is to ensure you open the proper ports for your system as shown in the rmi platform listings above.  The rmiRegistryPortPlatform makes the initial connection on port 9055 and then sets that particular session to 9056 when the connection is acknowledged.  This prevents jmx from using random ports for communication so you can keep your firewall secure.

As you may have also noticed, there is a jmxremote.password and jmxremote.access file that needs to be created.  The format is below:

jmxremote.access –
{name of user}          {readwrite, read, or write}

jmxremote.password –
{name of user}          {password}

With the access file, you can either have readwrite, read, or write access for the user.   Just remember to replace what I have in curly brackets above with the correct information.

Once you restart tomcat, you will be able to use the remote JMX console.  To test to see if it is listening, just type:

netstat -al | grep 9055.

You can then open VisualVM and make a connection.  We will look at that in another lesson