56

I am trying to connect to a remote tomcat JMX instance using jConsole. But can't connect successfully. Any Idea?

I included the following option in remote tomcat catalina.sh:

JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote \
    -Dcom.sun.management.jmxremote.port=9004 \
    -Dcom.sun.management.jmxremote.ssl=false \
    -Dcom.sun.management.jmxremote.authenticate=false"
Dan Vinton
  • 24,811
  • 8
  • 35
  • 79
Niger
  • 3,646
  • 5
  • 26
  • 29
  • Are you running a packaged version of Tomcat or did you install it manually? One more thing, can you paste the full error? – Pascal Thivent Oct 21 '09 at 16:56
  • Similar question: https://stackoverflow.com/questions/151238/has-anyone-ever-got-a-remote-jmx-jconsole-to-work – Vadzim Nov 02 '17 at 13:44

12 Answers12

63

I had a similar, if not the same, problem. I could connect to the JMX server if I started jconsole locally on the machine.

It appears the RMI server was not listening on the correct ip. So, as was suggested in this related question, I added the following:

-Djava.rmi.server.hostname=<host ip>

to JAVA_OPTS as well, and then it worked.

Community
  • 1
  • 1
waxwing
  • 17,792
  • 8
  • 61
  • 81
36

I've collected information spread over the net, found with hints from other members.

Most pain caused by JMX is (imo) the fact that JMX opens a second dynamically allocated network port. A firewall (like iptables) will block this.

Solution for tomcat on linux :

use tomcat 6.0.24 or newer download catalina-jmx-remote.jar from apache tomcat extras (use browse on tomcat download page) copy it in the $CTALINA_HOME\lib

This allows you to set both ports used by JMX

edit Server section in your server.xml

<Server port="8005" ..>
  ...
  <Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="9840" rmiServerPortPlatform="9841"/>

set some environment variables (e.g. in setenv.sh)

CATALINA_OPTS="
  -Djava.rmi.server.hostname=IP-TO-LISTEN
  -Dcom.sun.management.jmxremote.password.file=$CATALINA_BASE/conf/jmxremote.password 
  -Dcom.sun.management.jmxremote.access.file=$CATALINA_BASE/conf/jmxremote.access 
  -Dcom.sun.management.jmxremote.ssl=false"

this activates access control for JMX

jmxremote.access will look like

monitorRole readonly
controlRole readwrite

end jmxremote.password will be

monitorRole tomcat
controlRole tomcat

(just simple spaces)

restart tomcat.

Now configure firewall on the server (e.g. iptables)

/etc/sysconfig/iptables

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 9840 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 9841 -j ACCEPT

and /etc/sysconfig/ip6tables

-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 9840 -j ACCEPT
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 9841 -j ACCEPT

restart iptables

Done!

Now use VisualVM or JConsole on your workstation to establish a connection to rmiRegistryPortPlatform, 9840 in our sample.

If there are no more firewalls between workstation and server it should work.

Hajo Thelen
  • 1,085
  • 1
  • 10
  • 16
12

Tried with Java 8

1. Add this to your java tomcat startup script:

-Dcom.sun.management.jmxremote.port=1616
-Dcom.sun.management.jmxremote.rmi.port=1616
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=localhost

for example add into bin/setenv.sh this:

export CATALINA_OPTS="$CATALINA_OPTS \
-Dcom.sun.management.jmxremote.port=1616 \
-Dcom.sun.management.jmxremote.rmi.port=1616 \
-Dcom.sun.management.jmxremote.local.only=true \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false "

2. Execute this on your computer.

  • Windows users:

    putty.exe -ssh user@remote-host -L 1616:remote-host:1616

  • Linux and Mac Users:

    ssh user@remote-host -L 1616:remote-host:1616

3. Start jconsole on your computer

jconsole localhost:1616

4. Have fun!

  • P.S.: during step 2, using ssh and -L you specify that the port 1616 on the local (client) host is to be forwarded to the remote side.
  • P.S.2.: you can specify same port for JMX and RMI conversations
freedev
  • 17,230
  • 4
  • 83
  • 98
  • thanks was able to run rmiregistry and rmicomm in a same port. This works without tomcat/conf/server.xml JMXRemoteLifecycleListener. Is there any issues should be aware of if not to use that listener? – Whome Dec 01 '15 at 18:03
  • @Whome Sorry, I missed your comment. Nope, in my experience there aren't counter indications. – freedev May 24 '17 at 06:42
8

what string are you using as the JMX connection url. I don't mean to point out the obvious but JConsole has a terrible interface and to me requires an overly complex url before it will connect to a remote jmx app. Mine looks like this:

service:jmx:rmi:///jndi/rmi://(hostname):(jmxport)/jmxrmi
Hkachhia
  • 4,130
  • 5
  • 35
  • 71
Matt
  • 81
  • 1
  • 1
3

Enable JMX in Tomcat8, successfully tested in my POC

1/ Download the catalina-jmx-remote.jar from apache website and place in $CATALINA_HOME/lib.

2/ Take server.xml / setenv.sh backup. Make the changes to server.xml like below-

<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />

3/ Make the changes to $CATALINA_BASE/bin/setenv.sh like -

[...]

JVM_OPTS="[...] 
-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.authenticate=true 
-Djava.rmi.server.hostname=<eth:0_IP>| <`hostname -i`> 
-Dcom.sun.management.jmxremote.password.file=/apps/data/apache-tomcat-8_8080/conf/jmxremote.password 
-Dcom.sun.management.jmxremote.access.file=/apps/data/apache-tomcat-8_8080/conf/jmxremote.access 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.local.only=false 
-Dcom.sun.management.jmxremote=true "

4/ Create these two files as - $touch $CATALINA_BASE/conf/jmxremote.password containing:

admin letmein

$touch $CATALINA_BASE/conf/jmxremote.access containing:

admin readwrite

$ chmod 600 jmxremote.password

5/ Restart tomcat and test on jconsole tool :)

$echo|telnet 10.105.14.90 10001
Michael Laffargue
  • 9,799
  • 6
  • 39
  • 74
Bkkv
  • 31
  • 2
2

What exactly do you mean when you say "But can't connect successfully."? Is there an error message? Try turning on logging in jconsole and see if that helps debug it.

To turn on jconsole logging, edit a file named logging.properties in the directory you will be running jconsole in, add:

handlers= java.util.logging.ConsoleHandler

.level=INFO

java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter

java.util.logging.ConsoleHandler.level = FINEST
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

javax.management.level=FINEST
javax.management.remote.level=FINEST

Then, start jconsole with:

jconsole -J-Djava.util.logging.config.file=logging.properties
joe p
  • 463
  • 2
  • 5
  • Joe, i am getting the following exception. Ignoring logging error suggest whats the issue at com.sun.jmx.remote.util.ClassLogger.finer(ClassLogger.java:130) at com.sun.jmx.remote.util.ClassLogger.trace(ClassLogger.java:88) at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:245) at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:227) at sun.tools.jconsole.ProxyClient.tryConnect(ProxyClient.java:334) at sun.tools.jconsole.ProxyClient.connect(ProxyClient.java:296) at sun.tools.jconsole.VMPanel$2.run(VMPanel.java:280) – Niger Aug 13 '09 at 13:47
  • Sorry, I had a typo in the logging.properties text. I edited my post, try making that file again and see if you can get some debugging info. – joe p Aug 13 '09 at 22:10
  • No we are not able to see the logs. Where does this created the logs? – Java Guy May 04 '11 at 22:58
2

if you are working on linux, modify the catalina.sh file adding:

                CATALINA_OPTS="-Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=<HOST_IP> -Dcom.sun.management.jmxremote.port=<HOST_PORT> -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
            export CATALINA_OPTS

or modify the /etc/profile file as root and rerun the file (source /etc/profile)

if you are working on windows and you are starting tomcat from the command line, use the environment variable CATALINA_OPTS

if you are working on windows and you are starting tomcat as a service, you'll need to use the monitor service utility to configure the service initialization parameters (neither setenv.bat, catalina.bat or env-vars will work). for that you'll need the service name that appears listed in services.msc (for example jasperreportsTomcat). After, you'll need to open a console as administrator and execute (for example): tomcat6w.exe //MS//jasperreportsTomcat

with this command will appear a tray icon where you can open a panel. In the "Java" tab now you can modify the jmx options. Be careful to not add trailing whitespaces and use the "[enter]" symbol to separate each option line by line.

-Dcom.sun.management.jmxremote
-Djava.rmi.server.hostname=192.168.61.101
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false

Hope it helps

andhdo
  • 905
  • 7
  • 11
1

I got something for all of you, in order to complete the investigation of this whole thing. There is a trick, it happens that profiler tool connnects with the jvm using a port, but the jvm continues the conversation using another random port. If the jvm is running inside a remote machine (for example : a tomcat web-app server), and the remote machine has protection against outgoing and incoming connections, you must set the java system property com.sun.management.jmxremote.rmi.port to the same value of the property named com.sun.management.jmxremote.port

Source : https://serverfault.com/questions/308662/how-do-i-fix-a-failed-to-retrieve-rmiserver-stub-jmx-error And also check this out : http://blog.cantremember.com/debugging-with-jconsole-jmx-ssh-tunnels/

Hope to contribute guys!

And good luck!

Community
  • 1
  • 1
Victor
  • 3,348
  • 2
  • 29
  • 55
1

Check if your server is behind the firewall. JMX is base on RMI, which open two port when it start. One is the register port, default is 1099, and can be specified by the com.sun.management.jmxremote.port option. The other is for data communication, and is random, which is what cause problem. A good news is that, from JDK6, this random port can be specified by the com.sun.management.jmxremote.rmi.port option.

add the line in you {tomcat_dir}/bin/setenv.sh:

export CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8991 -Dcom.sun.management.jmxremote.rmi.port=8991 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
arganzheng
  • 1,103
  • 13
  • 18
0

PROTIP: You need to fix (as in having a known number) the RMI Registry and JMX/RMI Server ports. You do this by putting jar-file in the lib-dir and configuring a special listener. (And ofcourse the usual flags for activating JMX

    -Dcom.sun.management.jmxremote  \
    -Dcom.sun.management.jmxremote.port=8999 \
    -Dcom.sun.management.jmxremote.ssl=false \
    -Dcom.sun.management.jmxremote.authenticate=false \
    -Djava.rmi.server.hostname=<HOSTNAME> \

See: JMX Remote Lifecycle Listener at http://tomcat.apache.org/tomcat-6.0-doc/config/listeners.html

Adriaan Koster
  • 14,226
  • 4
  • 41
  • 56
supdog
  • 69
  • 2
  • 3
0

Changing the /etc/hosts on linux, where I replaced the localhost address associated to my account to the machine ip, solved this problem for me.

gunr2171
  • 10,315
  • 25
  • 52
  • 75
PedroG
  • 63
  • 7
0

Well, I had this problem in a Linux box (virtual machine) and I fixed it using -Djava.rmi.server.hostname property but there's a thing I can't understand. My machine has 5 tomcat servers, all of them has jmx enabled in consecutive ports (8008,8018,8028...) and only one of them had this issue connecting JMX. No firewall, no -Djava.rmi.server.hostname property in any tomcat....

So the thing is that I understand the problem but I can't understand why 4 of my tomcats worked and 1 of them not.

P.D: My english is very poor, I know. My Apologies.