Java: GarbageCollectorMXBean getCollectionCount throws java.io.IOException: client was closed

I am writing a Java application where I use the GarbageCollectorMXBean Java GarbageCollectorMXBean to get a collection counter at regular intervals (every 5 seconds). Below is the program that I wrote to complete the task.

 import java.io.IOException; import java.lang.management.GarbageCollectorMXBean; import java.lang.management.ManagementFactory; import java.util.HashMap; import java.util.Map; import javax.management.MBeanServerConnection; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; public class JMXTest { public static final String GC_NAME = "java.lang:name=MarkSweepCompact,type=GarbageCollector"; private static GarbageCollectorMXBean garbageCollectorMXBean; private static JMXConnector jmxConnector; private static MBeanServerConnection mbsc; public static void main(String[] args) throws Exception { String rmiHostname = "jmxserver"; String defaultUrl = "service:jmx:rmi:///jndi/rmi://" + rmiHostname + ":1999/jmxrmi"; JMXServiceURL jmxServiceURL = new JMXServiceURL(defaultUrl); Map<String,Object> jmxCredentials = new HashMap<String,Object>(); String[] credentials = new String[]{"jmxusername", "jmxpassword"}; jmxCredentials.put("jmx.remote.credentials", credentials); boolean run = true; while(run){ try { if(garbageCollectorMXBean == null){ if (mbsc == null){ jmxConnector = JMXConnectorFactory.connect(jmxServiceURL, jmxCredentials); mbsc = jmxConnector.getMBeanServerConnection(); } garbageCollectorMXBean = ManagementFactory.newPlatformMXBeanProxy(mbsc, GC_NAME,GarbageCollectorMXBean.class); } long count = garbageCollectorMXBean.getCollectionCount(); System.out.println("Garbage Collector count = " + count); } catch (Exception e) { e.printStackTrace(); garbageCollectorMXBean = null; if (jmxConnector != null) { try { jmxConnector.close(); } catch (IOException ioe) {} jmxConnector = null; } mbsc = null; } Thread.currentThread().sleep(5000); } } 

}

The program works fine, but sometimes it starts to throw the next IOException several times in each loop.

 Exception in thread "main" java.io.IOException: The client has been closed. at java.util.TimerThread.run(Timer.java:505) 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:1470) at javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection.getAttribute(RMIConnector.java:906) at com.ibm.lang.management.OpenTypeMappingIHandler$6.run(OpenTypeMappingIHandler.java:506) at java.security.AccessController.doPrivileged(AccessController.java:330) at com.ibm.lang.management.OpenTypeMappingIHandler.invokeAttributeGetter(OpenTypeMappingIHandler.java:501) at com.ibm.lang.management.OpenTypeMappingIHandler.invoke(OpenTypeMappingIHandler.java:121) at com.sun.proxy.$Proxy112.getCollectionCount(Unknown Source) at JMXTest.main(JMXTest.java:48) 

When looking at the code, any exception falls into the catch block, where all fields will be initialized to zero, and in the next loop, all fields will be reinitialized. But, looking at the logs as soon as the exception starts, I get the above exceptions only when getCollectionCount() called in each loop. Interestingly, although the objects are reinitialized every time I get the same exception.

I am considering the following things from the information above.

  • In all cases, we get this java.io.IOException: The client has been closed. exception java.io.IOException: The client has been closed. in the above scenario. I know if we call jmxConnector.close() and then use the already created GarbageCollectorMXBean object to get the collection count, we get this. But my code does not follow this path.
  • For the above problem, does jmxserver remote JMX server? I tried to play by stopping / restarting the remote JMX server, but could not do it.
+5
source share
1 answer

judging by the last line of the stack trace:

 at com.sun.proxy.$Proxy112.getCollectionCount(Unknown Source) at JMXTest.main(JMXTest.java:48) 

It seems the problem is with the line of code

 if (jmxConnector != null) { try { jmxConnector.close(); } catch (IOException ioe) {} jmxConnector = null; //...line no.48 } mbsc = null; //......this is probably causing the issue 

@raghavendra, since you are acquiring the "MBeanServerConnection" object from the "JMXConnector", you must close the objects / nullify them in that order, that is, change your code to

 if (jmxConnector != null) { try { mbsc = null; //...object handle assigned null before closing the connector jmxConnector.close(); } catch (IOException ioe) {} jmxConnector = null; } 
0
source

Source: https://habr.com/ru/post/1200608/


All Articles