Repository: incubator-unomi
Updated Branches:
  refs/heads/master ddbebd25f -> e61412fc9


As Apache JIRA is down, this is a fix for on OutOfMemory : native thread limit 
reached problem because we were not properly closing or re-using the JMX 
connectors. This modification should fix the problem by re-using JMX connectors 
and storing them in a map where they are stored by URL. Upon the service 
shutdown all the connectors are closed. When a connector is used, it is first 
tested and if it fails it is removed from the map and a new one is created.

Signed-off-by: Serge Huber <[email protected]>


Project: http://git-wip-us.apache.org/repos/asf/incubator-unomi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-unomi/commit/e61412fc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-unomi/tree/e61412fc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-unomi/diff/e61412fc

Branch: refs/heads/master
Commit: e61412fc90abc210d638c8b8cb848efd4be057a4
Parents: ddbebd2
Author: Serge Huber <[email protected]>
Authored: Thu Jan 12 17:47:17 2017 +0100
Committer: Serge Huber <[email protected]>
Committed: Thu Jan 12 17:47:17 2017 +0100

----------------------------------------------------------------------
 .../services/services/ClusterServiceImpl.java   | 62 ++++++++++++++------
 1 file changed, 44 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/e61412fc/services/src/main/java/org/apache/unomi/services/services/ClusterServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/services/src/main/java/org/apache/unomi/services/services/ClusterServiceImpl.java
 
b/services/src/main/java/org/apache/unomi/services/services/ClusterServiceImpl.java
index 8fb67d3..a002b55 100644
--- 
a/services/src/main/java/org/apache/unomi/services/services/ClusterServiceImpl.java
+++ 
b/services/src/main/java/org/apache/unomi/services/services/ClusterServiceImpl.java
@@ -70,6 +70,8 @@ public class ClusterServiceImpl implements ClusterService {
     private String secureAddress;
     private String securePort;
 
+    private Map<String,JMXConnector> jmxConnectors = new LinkedHashMap<>();
+
     PersistenceService persistenceService;
 
     public void setPersistenceService(PersistenceService persistenceService) {
@@ -178,6 +180,15 @@ public class ClusterServiceImpl implements ClusterService {
     }
 
     public void destroy() {
+        for (Map.Entry<String,JMXConnector> jmxConnectorEntry : 
jmxConnectors.entrySet()) {
+            String url = jmxConnectorEntry.getKey();
+            JMXConnector jmxConnector = jmxConnectorEntry.getValue();
+            try {
+                jmxConnector.close();
+            } catch (IOException e) {
+                logger.error("Error closing JMX connector for url {}", url, e);
+            }
+        }
     }
 
     @Override
@@ -224,32 +235,19 @@ public class ClusterServiceImpl implements ClusterService 
{
                 clusterNode.setData(false);
             }
             try {
-                // now let's connect to remote JMX service to retrieve 
information from the runtime and operating system MX beans
-                JMXServiceURL url = new 
JMXServiceURL("service:jmx:rmi:///jndi/rmi://"+karafCellarNode.getHost() + 
":"+karafJMXPort+"/karaf-root");
-                Map<String,Object> environment=new HashMap<String,Object>();
-                if (karafJMXUsername != null && karafJMXPassword != null) {
-                    environment.put(JMXConnector.CREDENTIALS,new 
String[]{karafJMXUsername,karafJMXPassword});
-                }
-                JMXConnector jmxc = JMXConnectorFactory.connect(url, 
environment);
-                MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
+                String serviceUrl = 
"service:jmx:rmi:///jndi/rmi://"+karafCellarNode.getHost() + 
":"+karafJMXPort+"/karaf-root";
+                JMXConnector jmxConnector = getJMXConnector(serviceUrl);
+                MBeanServerConnection mbsc = 
jmxConnector.getMBeanServerConnection();
                 final RuntimeMXBean remoteRuntime = 
ManagementFactory.newPlatformMXBeanProxy(mbsc, 
ManagementFactory.RUNTIME_MXBEAN_NAME, RuntimeMXBean.class);
                 clusterNode.setUptime(remoteRuntime.getUptime());
                 ObjectName operatingSystemMXBeanName = new 
ObjectName(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME);
-                Double processCpuLoad = null;
                 Double systemCpuLoad = null;
                 try {
-                    processCpuLoad = (Double) 
mbsc.getAttribute(operatingSystemMXBeanName, "ProcessCpuLoad");
-                } catch (MBeanException e) {
-                    e.printStackTrace();
-                } catch (AttributeNotFoundException e) {
-                    e.printStackTrace();
-                }
-                try {
                     systemCpuLoad = (Double) 
mbsc.getAttribute(operatingSystemMXBeanName, "SystemCpuLoad");
                 } catch (MBeanException e) {
-                    e.printStackTrace();
+                    logger.error("Error retrieving system CPU load", e);
                 } catch (AttributeNotFoundException e) {
-                    e.printStackTrace();
+                    logger.error("Error retrieving system CPU load", e);
                 }
                 final OperatingSystemMXBean remoteOperatingSystemMXBean = 
ManagementFactory.newPlatformMXBeanProxy(mbsc, 
ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME, OperatingSystemMXBean.class);
                 clusterNode.setLoadAverage(new double[] { 
remoteOperatingSystemMXBean.getSystemLoadAverage()});
@@ -301,4 +299,32 @@ public class ClusterServiceImpl implements ClusterService {
         return support.isAllowed(group, category, pid, type);
     }
 
+    private JMXConnector getJMXConnector(String url) throws IOException {
+        if (jmxConnectors.containsKey(url)) {
+            JMXConnector jmxConnector = jmxConnectors.get(url);
+            try {
+                jmxConnector.getMBeanServerConnection();
+                return jmxConnector;
+            } catch (IOException e) {
+                jmxConnectors.remove(url);
+                try {
+                    jmxConnector.close();
+                } catch (IOException e1) {
+                    logger.error("Error closing invalid JMX connection", e1);
+                }
+                logger.error("Error using the JMX connection to url {}, closed 
and will reconnect", url, e);
+            }
+        }
+        // if we reach this point either we didn't have a connector or it 
didn't validate
+        // now let's connect to remote JMX service to retrieve information 
from the runtime and operating system MX beans
+        JMXServiceURL jmxServiceURL = new JMXServiceURL(url);
+        Map<String,Object> environment=new HashMap<String,Object>();
+        if (karafJMXUsername != null && karafJMXPassword != null) {
+            environment.put(JMXConnector.CREDENTIALS,new 
String[]{karafJMXUsername,karafJMXPassword});
+        }
+        JMXConnector jmxConnector = JMXConnectorFactory.connect(jmxServiceURL, 
environment);
+        jmxConnectors.put(url, jmxConnector);
+        return jmxConnector;
+    }
+
 }

Reply via email to