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.
source share