Multi threading JMX client

Dinanjana

I am trying to implement a JMXclient to monitor remote JVM. I obtain the mbeanserver connection from a main method and pass it to a thread which search for memory usage. Problem is when I do this i get an error saying "The client has been closed". But if I run the program without threads it works perfectly.

public class ESBMonitor {
     private static TreeSet<ObjectName> mbeansNames = null;

     public static void main(String[] args) throws IOException {
         RemoteConnector.defaultConnector();
         MBeanServerConnection remote = RemoteConnector.getRemote();
         //MemoryExtractor.getMemoryInfo();
         MemoryExtractor memoryExtractor = new MemoryExtractor();
         memoryExtractor.start();
         RemoteConnector.closeConnection();
     }
}



public class RemoteConnector {

private static MBeanServerConnection remote = null;
private static JMXConnector connector = null;
private static final Logger logger= LogManager.getLogger(RemoteConnector.class);

public static void defaultConnector() {
    try {
        JMXServiceURL target = new JMXServiceURL
                ("service:jmx:rmi://localhost:11111/jndi/rmi://localhost:9999/jmxrmi");
        //for passing credentials for password
        Map<String, String[]> env = new HashMap<String, String[]>();
        String[] credentials = {"admin", "admin"};
        env.put(JMXConnector.CREDENTIALS, credentials);

        connector = JMXConnectorFactory.connect(target, env);
        remote = connector.getMBeanServerConnection();
        logger.info("MbeanServer connection obtained");

    } catch (MalformedURLException e) {
        logger.error(e.getStackTrace());
    } catch (IOException e) {
        logger.error(e.getStackTrace());
    }
}

public static MBeanServerConnection getRemote() {
    return remote;
}



public static synchronized Object getMbeanAttribute(ObjectName bean, String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException, InstanceNotFoundException, IOException {
    return remote.getAttribute(bean,attribute);
}


}




public class MemoryExtractor extends Thread{

final static Logger logger = Logger.getLogger(MemoryExtractor.class);
private static MBeanInfo memoryInfo;
private static ObjectName bean = null;
private static double MEMORY = 0.05;
private static long TIMEOUT = 3000;

public static void getMemoryInfo() {
    try {
        bean = new ObjectName("java.lang:type=Memory");
        checkWarningUsage();

    } catch (MalformedObjectNameException e) {
        logger.error("MemoryExtractor.java:25 " + e.getMessage());
    }
}

public static boolean checkWarningUsage() {
        try {
            logger.info("MemoryExtractor.java:46 Acessing memory details");
            CompositeData memoryUsage = (CompositeData) RemoteConnector.getMbeanAttribute(bean,"HeapMemoryUsage");


        } catch (Exception e) {
            logger.error("MemoryExtractor.java:58 " + e.getMessage());
        }
    return false;
}

public void run(){
    while (true){
        getMemoryInfo();
    }   
}
}

No matter I synchronize or not problem will still be there.

Stack trace

java.io.IOException: The client has been closed.
at com.sun.jmx.remote.internal.ClientCommunicatorAdmin.restart(ClientCommunicatorAdmin.java:94)
at com.sun.jmx.remote.internal.ClientCommunicatorAdmin.gotIOException(ClientCommunicatorAdmin.java:54)
at javax.management.remote.rmi.RMIConnector$RMIClientCommunicatorAdmin.gotIOException(RMIConnector.java:1474)
at javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection.getAttribute(RMIConnector.java:910)
at org.wso2.connector.RemoteConnector.getMbeanAttribute(RemoteConnector.java:55)
at org.wso2.jvmDetails.MemoryExtractor.checkWarningUsage(MemoryExtractor.java:47)
at org.wso2.jvmDetails.MemoryExtractor.run(MemoryExtractor.java:79)
AlBlue

You are caching the reference to the JMXConnector as a static in your RemoteConnector class, so there's only ever one connection. As soon as the first thread closes that singleton connection, the next time any other thread attempts to call something it will fail because you've already closed the connection at that point.

If you want to have multiple threads, then either you should close the connection when all threads have finished, or have one connection per thread.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related