[java] Remote JMX connection

I'm trying to open a JMX connection to java application running on a remote machine.

The application JVM is configured with the following options:

  • com.sun.management.jmxremote
  • com.sun.management.jmxremote.port=1088
  • com.sun.management.jmxremote.authenticate=false
  • com.sun.management.jmxremote.ssl=false

I'm able to connect using localhost:1088 using jconsole or jvisualvm. But I'm not able to connect using xxx.xxx.xxx.xxx:1088 from a remote machine.

There is no firewall between the servers, or on the OS. But to eliminate this possibility I telnet xxx.xxx.xxx.xxx 1088 and I think it connects, as the console screen turns blank.

Both servers are Windows Server 2008 x64. Tried with 64-bit JVM and 32-bit, neither work.

This question is related to java jmx jconsole

The answer is


I know this thread is pretty old, but there's an additional option that will help greatly. See here: https://realjenius.com/2012/11/21/java7-jmx-tunneling-freedom/

-Dcom.sun.management.jmxremote.rmi.port=1099


In my testing with Tomcat and Java 8, the JVM was opening an ephemeral port in addition to the one specified for JMX. The following code fixed me up; give it a try if you are having issues where your JMX client (e.g. VisualVM is not connecting.

-Dcom.sun.management.jmxremote.port=8989
-Dcom.sun.management.jmxremote.rmi.port=8989

Also see Why Java opens 3 ports when JMX is configured?


it seams that your ending quote comes too early. It should be after the last parameter.

This trick worked for me.

I noticed something interesting: when I start my application using the following command line:

java -Dcom.sun.management.jmxremote.port=9999
     -Dcom.sun.management.jmxremote.authenticate=false
     -Dcom.sun.management.jmxremote.ssl=false

If I try to connect to this port from a remote machine using jconsole, the TCP connection succeeds, some data is exchanged between remote jconsole and local jmx agent where my MBean is deployed, and then, jconsole displays a connect error message. I performed a wireshark capture, and it shows data exchange coming from both agent and jconsole.

Thus, this is not a network issue, if I perform a netstat -an with or without java.rmi.server.hostname system property, I have the following bindings:

 TCP    0.0.0.0:9999           0.0.0.0:0              LISTENING
 TCP    [::]:9999              [::]:0                 LISTENING

It means that in both cases the socket created on port 9999 accepts connections from any host on any address.

I think the content of this system property is used somewhere at connection and compared with the actual IP address used by agent to communicate with jconsole. And if those address do not match, connection fails.

I did not have this problem while connecting from the same host using jconsole, only from real physical remote hosts. So, I suppose that this check is done only when connection is coming from the "outside".


I've spend more than a day trying to make JMX to work from outside localhost. It seems that SUN/Oracle failed to provide a good documentation on this.

Be sure that the following command returns you a real IP or HOSTNAME. If it does return something like 127.0.0.1, 127.0.1.1 or localhost it will not work and you will have to update /etc/hosts file.

hostname -i

Here is the command needed to enable JMX even from outside

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.port=1100
-Djava.rmi.server.hostname=myserver.example.com

Where as you assumed, myserver.example.com must match what hostname -i returns.

Obviously, you need to be sure that the firewall does not block you, but I'm almost sure that this is not your problem, the problem being the last parameter that is not documented.


To enable JMX remote, pass below VM parameters along with JAVA Command.

    -Dcom.sun.management.jmxremote 
    -Dcom.sun.management.jmxremote.port=453
    -Dcom.sun.management.jmxremote.authenticate=false                               
    -Dcom.sun.management.jmxremote.ssl=false 
    -Djava.rmi.server.hostname=myDomain.in

Try this, I tested to access JMX inside docker container

-Dcom.sun.management.jmxremote=true -Djava.rmi.server.hostname=localhost -Dcom.sun.management.jmxremote.port=16000 -Dcom.sun.management.jmxremote.rmi.port=16000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false

Then

$ jconsole localhost:16000


the thing that work for me was to set /etc/hosts to point the hostname to the ip and not to the loopback interface and than restart my application.

cat /etc/hosts

127.0.0.1      localhost.localdomain localhost
192.168.0.1    myservername

This is my configuration:

-Dcom.sun.management.jmxremote.port=1617 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.authenticate=false

http://blogs.oracle.com/jmxetc/entry/troubleshooting_connection_problems_in_jconsole

If you are trying to access a server which is behind a NAT - you will most probably have to start your server with the option

-Djava.rmi.server.hostname=<public/NAT address>

so that the RMI stubs sent to the client contain the server's public address allowing it to be reached by the clients from the outside.


Thanks a lot, it works like this:

java -Djava.rmi.server.hostname=xxx.xxx.xxx.xxx -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=25000 -jar myjar.jar


I have the same issue and I change any hostname that matches the local host name to 0.0.0.0, it seems to work after I do that.


Try using ports higher than 3000.