title: Multi threading JMX client
body: <p>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.</p>
  
  <pre><code>public class ESBMonitor {
       private static TreeSet&lt;ObjectName&gt; 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&lt;String, String[]&gt; env = new HashMap&lt;String, String[]&gt;();
          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();
      }   
  }
  }
  </code></pre>
  
  <p>No matter I synchronize or not problem will still be there.</p>
  
  <p>Stack trace </p>
  
  <pre><code>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)
  </code></pre>