At work I support a number of different Java applications. Sadly they’re not all well behaved and it’s sometimes necessary to have to connect to the JMX port with Jconsole and take a look at what’s going on.
This is usually easy enough when dealing with a local application, or an application on a LAN with very lax firewall policies, however in a hardened hosting environment with tight policies, it can be more difficult.
Even if the JMX port is permitted by your firewall policies, there’s another challange due to Jconsole needing to also connect to the RMI port, which can vary and is unlikely to be included in your firewall policies. This also makes it hard to do SSH port forwarding, since you have to find out what port is in use each time, and it just gets messy.
Thankfully there is an easier way using good old SSH – this will work with GNU/Linux and MacOS (Windows users will need to figure out the equivalent Putty configuration).
Firstly, open an SSH SOCKS proxy connection with:
ssh -D 1234 myjavapp.example.com
Secondly in a different shell, launch Jconsole, passing parameters to use the SOCKS proxy for all connections. Assuming that the JMX is listening on 7199, you’d end up with:
jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=1234 \ service:jmx:rmi:///jndi/rmi://localhost:7199/jmxrmi
And you’re in, through any firewalls and SSH ensures your connection is properly encrypted. If opening multiple Jconsole connections, you just need to establish a different SOCKS proxy port connection each time.
If your application isn’t currently providing a JMX listening port, the following configuration will setup the JMX port. Note that this configuration has no authentication, so anyone with an account on the server could connect to the JMX, or if the server lacks a firewall, from other network locations.
-Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port=7199 \ -Dcom.sun.management.jmxremote.ssl=false \ -Dcom.sun.management.jmxremote.authenticate=false
These parameters need to get added to the Java startup parameters for your application… this varies a lot by application/platform, but look for JAVA_OPTS or a startup script of some kind and trace through form there.
Great article! I have been trying to troubleshoot a monitoring tool that would not connect to my JMX instance. I ran through this and it worked fine. Now my question is this.. My network team ensures me that the JMX port is open and the monitoring server has access to my java server in question. What else could be preventing the jmx connection remotely? Should I set a RMI port in the java_opts?