98

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.

tuler
  • 3,084
  • 5
  • 30
  • 42
  • 1
    Probably related to http://stackoverflow.com/questions/151238/has-anyone-ever-got-a-remote-jmx-jconsole-to-work – tuler May 07 '09 at 16:46
  • Here is detailed guide http://stackoverflow.com/a/11654322/99834 – sorin Jul 25 '12 at 16:25

12 Answers12

119

Had it been on Linux the problem would be that localhost is the loopback interface, you need to application to bind to your network interface.

You can use the netstat to confirm that it is not bound to the expected network interface.

You can make this work by invoking the program with the system parameter java.rmi.server.hostname="YOUR_IP", either as an environment variable or using

java -Djava.rmi.server.hostname=YOUR_IP YOUR_APP
Rob Kielty
  • 7,464
  • 7
  • 35
  • 50
takete.dk
  • 2,575
  • 1
  • 18
  • 12
  • 7
    Don't forget about `hostname -i`, see http://stackoverflow.com/a/11654322/99834 for details. – sorin Jul 25 '12 at 16:26
  • Worked! In our environment we use VMWare virtual machines. The server was on a VM. The VM was deployed fenced so it has internal and an external IP addresses. We started the server java process with -Djava.rmi.server.hostname=. – buzz3791 Oct 28 '13 at 21:39
  • To set the host ip or change the localhost ip this [link](http://stackoverflow.com/a/23338592/1635051) would be useful. – Reza Ameri Apr 28 '14 at 10:27
  • I have two questions here - 1) What if one wants to use JMXMP rather than JMX. What would be the configs for that? and 2) Is it possible to make the JMX connection without loading the RMI protocol? – Kumar Vaibhav Feb 17 '15 at 12:12
66

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.

sorin
  • 137,198
  • 150
  • 472
  • 707
  • Adding -Djava.rmi.server.hostname=myserver.example.com did the trick! Thanks! – Jim Bethancourt Apr 04 '14 at 16:22
  • I took the liberty of opening a JDK docs bugs for this: https://bugs.openjdk.java.net/browse/JDK-8066405 – Klara Dec 02 '14 at 09:44
  • 3
    "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." What? – PedroD May 07 '15 at 13:40
  • 1
    Just a quick not, the `java.rmi.server.hostname=`. Hope this helps someone. – Sonny Feb 14 '16 at 21:18
  • @PedroD: YOu need to an an entry to /etx/hosts with your public IP and the hostname you use for "-Djava.rmi.server.hostname" – Sebastian Oct 13 '20 at 21:58
24

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?

Community
  • 1
  • 1
LeslieM
  • 1,539
  • 12
  • 7
12

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.

gnat
  • 6,199
  • 101
  • 49
  • 71
h0nIg
  • 121
  • 1
  • 2
8

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".

yohann.martineau
  • 1,293
  • 14
  • 20
  • What do you mean by "your ending quote comes too early"? I have the same problem, I see the TCP connection being made, but eventually jconsole claims it failed to connect. – tsuna Apr 03 '13 at 22:28
  • I don't know, if I remember correctly, there was a quote open somewhere and this quote was not at the end of parameters. Maybe it was in a batch script, I can't remember. But I must admit this answer makes no sense regarding the question... Maybe the question has been edited? No edited notification under the question... I don't know, I'm sorry. – yohann.martineau Apr 05 '13 at 07:13
6

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
Maoz Zadok
  • 2,984
  • 1
  • 19
  • 29
5

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

user3406690
  • 51
  • 1
  • 1
1

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

Jonathan S. Fisher
  • 7,058
  • 6
  • 37
  • 78
0

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.

ianpojman
  • 1,643
  • 1
  • 15
  • 20
0

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
Ajay Kumar
  • 3,408
  • 30
  • 35
0

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

Emmerson
  • 51
  • 3
-11

Try using ports higher than 3000.