Author: davsclaus Date: Wed Jan 2 07:11:25 2013 New Revision: 1427688 URL: http://svn.apache.org/viewvc?rev=1427688&view=rev Log: CAMEL-5907 Fixed the Camel leaks memory on undeploy / redeploy in app server when JMX enabled and createConnector = true with thanks to Daniel
Modified: camel/branches/camel-2.9.x/ (props changed) camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java camel/branches/camel-2.9.x/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationWithConnectorTest.java Propchange: camel/branches/camel-2.9.x/ ------------------------------------------------------------------------------ Merged /camel/trunk:r1425724 Merged /camel/branches/camel-2.10.x:r1427682 Propchange: camel/branches/camel-2.9.x/ ------------------------------------------------------------------------------ Binary property 'svnmerge-integrated' - no diff available. Modified: camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java?rev=1427688&r1=1427687&r2=1427688&view=diff ============================================================================== --- camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java (original) +++ camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java Wed Jan 2 07:11:25 2013 @@ -20,8 +20,11 @@ import java.io.IOException; import java.lang.management.ManagementFactory; import java.net.InetAddress; import java.net.UnknownHostException; +import java.rmi.NoSuchObjectException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.rmi.server.UnicastRemoteObject; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -58,9 +61,10 @@ public class DefaultManagementAgent exte private CamelContext camelContext; private MBeanServer server; - // need a name -> actual name mapping as some servers changes the names (suc as WebSphere) + // need a name -> actual name mapping as some servers changes the names (such as WebSphere) private final Map<ObjectName, ObjectName> mbeansRegistered = new HashMap<ObjectName, ObjectName>(); private JMXConnectorServer cs; + private Registry registry; private Integer registryPort; private Integer connectorPort; @@ -257,7 +261,7 @@ public class DefaultManagementAgent exte } protected void doStop() throws Exception { - // close JMX Connector + // close JMX Connector, if it was created if (cs != null) { try { cs.stop(); @@ -269,6 +273,16 @@ public class DefaultManagementAgent exte cs = null; } + // Unexport JMX RMI registry, if it was created + if (registry != null) { + try { + UnicastRemoteObject.unexportObject(registry, true); + LOG.debug("Unexported JMX RMI Registry"); + } catch (NoSuchObjectException e) { + LOG.debug("Error occurred while unexporting JMX RMI registry. This exception will be ignored."); + } + } + if (mbeansRegistered.isEmpty()) { return; } @@ -385,7 +399,7 @@ public class DefaultManagementAgent exte try { - LocateRegistry.createRegistry(registryPort); + registry = LocateRegistry.createRegistry(registryPort); LOG.debug("Created JMXConnector RMI registry on port {}", registryPort); } catch (RemoteException ex) { // The registry may had been created, we could get the registry instead Modified: camel/branches/camel-2.9.x/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationWithConnectorTest.java URL: http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationWithConnectorTest.java?rev=1427688&r1=1427687&r2=1427688&view=diff ============================================================================== --- camel/branches/camel-2.9.x/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationWithConnectorTest.java (original) +++ camel/branches/camel-2.9.x/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationWithConnectorTest.java Wed Jan 2 07:11:25 2013 @@ -19,8 +19,12 @@ package org.apache.camel.management; import java.io.IOException; import java.net.DatagramSocket; import java.net.ServerSocket; +import java.rmi.NoSuchObjectException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; import java.util.Locale; import java.util.NoSuchElementException; +import java.util.Random; import javax.management.MBeanServerConnection; import javax.management.remote.JMXConnector; @@ -37,6 +41,7 @@ public class JmxInstrumentationWithConne protected String url; protected JMXConnector clientConnector; + protected int registryPort; @Override protected boolean useJmx() { @@ -55,14 +60,14 @@ public class JmxInstrumentationWithConne protected void setUp() throws Exception { sleepForConnection = 3000; - int port = getNextAvailable(9500); - log.info("Using port " + port); - url = "service:jmx:rmi:///jndi/rmi://localhost:" + port + "/jmxrmi/camel"; + registryPort = 30000 + new Random().nextInt(10000); + log.info("Using port " + registryPort); + url = "service:jmx:rmi:///jndi/rmi://localhost:" + registryPort + "/jmxrmi/camel"; // need to explicit set it to false to use non-platform mbs System.setProperty(JmxSystemPropertyKeys.USE_PLATFORM_MBS, "false"); System.setProperty(JmxSystemPropertyKeys.CREATE_CONNECTOR, "true"); - System.setProperty(JmxSystemPropertyKeys.REGISTRY_PORT, String.valueOf(port)); + System.setProperty(JmxSystemPropertyKeys.REGISTRY_PORT, "" + registryPort); super.setUp(); } @@ -90,34 +95,31 @@ public class JmxInstrumentationWithConne return mbsc; } - private synchronized int getNextAvailable(int fromPort) { - ServerSocket ss = null; - DatagramSocket ds = null; - - for (int port = fromPort; port <= 49151; port++) { - try { - ss = new ServerSocket(port); - ss.setReuseAddress(true); - ds = new DatagramSocket(port); - ds.setReuseAddress(true); - return port; - } catch (IOException e) { - // Do nothing - } finally { - if (ds != null) { - ds.close(); - } - - if (ss != null) { - try { - ss.close(); - } catch (IOException e) { - /* should not be thrown */ - } - } - } + public void testRmiRegistryUnexported() throws Exception { + + Registry registry = LocateRegistry.getRegistry(registryPort); + + // before we stop the context the registry is still exported, so list() should work + Exception e; + try { + registry.list(); + e = null; + } catch (NoSuchObjectException nsoe) { + e = nsoe; } + assertNull(e); + + // stop the Camel context + context.stop(); - throw new NoSuchElementException("Could not find an available port above " + fromPort); + // stopping the Camel context unexported the registry, so list() should fail + Exception e2; + try { + registry.list(); + e2 = null; + } catch (NoSuchObjectException nsoe) { + e2 = nsoe; + } + assertNotNull(e2); } }