I am writing a Java application where I am using Java GarbageCollectorMXBean APIs to get the collection count at regular intervals (for every 5 seconds). Below is the program I have written to do 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=GarbageColle ctor"; 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); } }
he program runs fine but sometimes it starts giving following IOException repeatedly in every 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.ClientCommunicatorAdmi n.restart(ClientCommunicatorAdmin.java:94)
at com.sun.jmx.remote.internal.ClientCommunicatorAdmi n.gotIOException(ClientCommunicatorAdmin.java:54)
at javax.management.remote.rmi.RMIConnector$RMIClient CommunicatorAdmin.gotIOException(RMIConnector.java :1470)
at javax.management.remote.rmi.RMIConnector$RemoteMBe anServerConnection.getAttribute(RMIConnector.java: 906)
at com.ibm.lang.management.OpenTypeMappingIHandler$6. run(OpenTypeMappingIHandler.java:506)
at java.security.AccessController.doPrivileged(Access Controller.java:330)
at com.ibm.lang.management.OpenTypeMappingIHandler.in vokeAttributeGetter(OpenTypeMappingIHandler.java:5 01)
at com.ibm.lang.management.OpenTypeMappingIHandler.in voke(OpenTypeMappingIHandler.java:121)
at com.sun.proxy.$Proxy112.getCollectionCount(Unknown Source)
at JMXTest.main(JMXTest.java:48)
But if we look at the code, for any exception it will get caught in catch block where all the fields will be initialized to null and in the next loop all the fields will be reinitialized. But looking at the logs, Once the exception starts coming, I get above exception only at getCollectionCount() call in every loop. I wonder even though the objects are re initialized, every time I get same exception.
I am looking at following things from the above information
In what all cases, we get this 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 that path.
For the above issue, does jmxserver remote JMX server contributes ? I tried to reproduce by stopping/restarting the remote JMX server, but could not do it.
Any help in this regard ?