title: dynamic proxies with jmx can cause thread leaks?
body: <p>I have a problem in Java where I set up a dynamic proxy with a JMX interface, pass this on to another component which then makes calls to the proxy object. When I do this, the application leaks two threads for each call, threads which never seem to time out and keep building up until the application runs out of memory. </p>
  
  <p>The threads appear in pairs, see stacktrace at the bottom.</p>
  
  <p>I have tried using some slightly obscure system properties to turn off timeouts alltogether in JMX but it doesn't make a difference. The key action seems to be the dynamic proxy call. The object that is called through the proxy implements Serializable so that shouldn't be a problem.</p>
  
  <p>When I manually create a Bean with a string of the MBean path and the object interface and call the method from that, the problem disappears.</p>
  
  <p>I am mostly looking for classic gotchas here when it comes to dynamic proxies since I don't have too much experience with them.</p>
  
  <p>This is how the proxyinstance is created</p>
  
  <pre><code>public &lt;T&gt; T create(final Class&lt;T&gt; type,
          final Object... nameParameters) throws JmxConnectionException {
      return type.cast(Proxy.newProxyInstance(
              type.getClassLoader(),
              new Class&lt; ? &gt;[] {type},
              new MyInvocationHandler(this,
                      fill(nameOf(type), nameParameters))));
  }
  </code></pre>
  
  <p>and the implementation of MyInvocationHandler:</p>
  
  <pre><code>final class MyInvocationHandler implements InvocationHandler, Serializable {
  private static final long serialVersionUID = 0L; //actually a proper random long
  private final transient ProxyFactory proxyFactory;
  private String mBeanName;
  private RemoteObject remoteObject;
  
  MyInvocationHandler(final ProxyFactory proxyFactory,
          final String mBeanName) {
      this.proxyFactory = proxyFactory;
      this.mBeanName = mBeanName;
  }
  
  private void writeObject(final ObjectOutputStream out)
  throws IOException {
      try {
          checkConnected();
      } catch (final JmxConnectionException e) {
          throw new IOException(e);
      }
      out.writeObject(mBeanName);
      out.writeObject(remoteObject);
  }
  
  private void readObject(final ObjectInputStream in)
  throws IOException, ClassNotFoundException {
      mBeanName = (String) in.readObject();
      remoteObject = (RemoteObject) in.readObject();
  }
  
  public Object invoke(final Object proxy, final Method method,
          final Object[] args) throws Throwable {
      checkConnected(); //Just checks that the RemoteObject isn't null.
      try {
          return invokeMethod(method, args); // Calls the method on the remoteObject with the arguments, code cut.
      } catch (final InvocationTargetException e) {
          throw e.getCause();
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Thread stacktrace for the two threads (always appear in pairs):</p>
  
  <pre><code>Name: JMX server connection timeout 53
  State: TIMED_WAITING on [I@18bbe70
  Total blocked: 3  Total waited: 4
  
  Stack trace: 
  java.lang.Object.wait(Native Method)
  com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(ServerCommunicatorAdmin.java:150)
  java.lang.Thread.run(Thread.java:619)
  
  Name: Thread-21
  State: TIMED_WAITING
  Total blocked: 0  Total waited: 1
  
  Stack trace: 
  java.lang.Thread.sleep(Native Method)
  com.sun.jmx.remote.internal.ClientCommunicatorAdmin$Checker.run(ClientCommunicatorAdmin.java:154)
  java.lang.Thread.run(Thread.java:619)
  </code></pre>