Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot connect to remote JMX

Tags:

java

jconsole

I have a tomcat application on the remote host and need to connect it by JConsole. Application starts with params:

IP=`ifconfig eth0 | grep 'inet addr:' | cut -d ':' -f2 | cut -d ' ' -f1`

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

Port 9999 is open, IP value is valid, I checked it. I can access it by telnet (telnet <my_host> <my_port>). Netstat:

netstat -a | grep LISTEN
tcp        0      0 *:9999                  *:*                     LISTEN 

But I can't connect it via jconsole, I allways get same error:

Connection Failed: Retry?

But netstat -a shows that the connection is ESTABLISHED

I tried different addresses:

<my_host>:<my_port>

service:jmx:rmi://<my_host>:<my_port>/jndi/rmi://<my_host>:<my_port>/jmxrmi

service:jmx:rmi:///jndi/rmi://<my_host>:<my_port>/jmxrmi

I also tried to add files .../conf/remote.users and .../remote.acl and write pathes to that files in prorerties -Dcom.sun.management.jmxremote.password.file and -Dcom.sun.management.jmxremote.access.file but it had no effect.

When I deploy this app on my local machine, i can connect to it at "localhost:9999"

Help somebody, what could be the problem?

like image 742
Kirill Avatar asked Mar 14 '16 08:03

Kirill


People also ask

How do I pair my JMX Remote?

Remote JMX ConnectionsRight click anywhere in the blank area under the application tree and select Add JMX Connection. Provide the machine name and port number for a running JMX agent, that has been started with the appropriate system properties to allow remote management.

What is JMX remote port?

JMX Definition The Java Management Extensions (JMX) framework provides a configurable, scalable, and reliable infrastructure for managing Java applications. Furthermore, it defines a concept of MBean for real-time management of the application. The framework allows managing an application locally or remotely.

How do I find my JMX URL?

The RMI registry tells JMX clients where to find the JMX RMI server port; information can be obtained under key jmxrmi . The RMI registry port is generally known as it is set through system properties at JVM startup.


2 Answers

If you are able to telnet <my_host> <my_port> then issue must be because of Firewall, since in JMX once handshake done on configured port i.e then a new port is assigned for further communication and probably your Firwall is not allowing to open a new port.

To cross check simply try to run below Java JMX Client which will try to display HeapMemoryUsage.

import java.util.Set;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class JMXDemo {

    private static final String HOST = ""; // configure host <my_host> here
    private static final String PORT = ""; // configure port <my_port> here

    private static void testJMX() throws Exception {
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://" + HOST + "/jndi/rmi://" + HOST + ":" + PORT
                + "/jmxrmi");

        JMXConnector jmxConnector = JMXConnectorFactory.connect(url);
        try {
            MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection();

            ObjectName mbeanName = new ObjectName("java.lang:type=Memory");
            javax.management.openmbean.CompositeDataSupport obj = null;

            obj = (javax.management.openmbean.CompositeDataSupport) mbeanServerConnection.getAttribute(mbeanName,
                    "HeapMemoryUsage");
            Set<String> keySet = obj.getCompositeType().keySet();

            for (String key : keySet) {
                System.out.print(key + "=" + obj.get(key) + ", ");
            }
        } finally {
            jmxConnector.close();
        }
        System.out.println("\n==========================");
    }

    public static void main(String args[]) throws Exception {
        testJMX();
    }

}

To Enable JMX logging Create a logging.properties file

handlers= java.util.logging.ConsoleHandler
.level=ALL

java.util.logging.FileHandler.pattern = jmx.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

// Use FINER or FINEST for javax.management.remote.level - FINEST is
// very verbose...
//
javax.management.level=FINEST
javax.management.remote.level=FINEST

java.security.debug=all

Compile the java code and run using below command

 java -Djava.util.logging.config.file=./logging.properties JMXDemo 

This will print so many logs on console, you can grep "port".

like image 199
Mahendra Avatar answered Nov 04 '22 11:11

Mahendra


Write a basic Java program:

import java.util.*;
import java.io.*;

class testCode{
  public static void main(String args[]){
    System.out.println("just killing time...do not enter a value and kill me ");
    Scanner sc = new Scanner(System.in);
    sc.nextInt();
  }    
}

Compile and then run it with the following parameters:

java -Dcom.sun.management.jmxremote=true \
 -Dcom.sun.management.jmxremote.port=12345 \
 -Dcom.sun.management.jmxremote.authenticate=false \
 -Dcom.sun.management.jmxremote.ssl=false \
 -Djava.rmi.server.hostname=10.1.10.167 \
 testCode

Replace rmi.server.hostname with the IP of the machine where Java code is being executed, then use jconsole to remote connect with 10.1.10.167:12345. No user id and password required.

like image 25
Ajay V Avatar answered Nov 04 '22 10:11

Ajay V