title: Spring RMI refreshStubOnConnectFailure not working
body: <p>I read the following blog entry here,
  <a href="https://stackoverflow.com/questions/1477121/reconnect-rmi-client-after-server-restart/1485920#1485920">Reconnect RMI client after server restart</a></p>
  
  <p>It states that when the property refreshStubOnConnectFailure is set to true that my client RMI will try to reconnect to the server. So I wrote the following code to test it out before I put changes into my system. I started my server and then this test program. After a few messages that the server and client were talking I stopped the server. I got an exception trace but none of my catch blocks was entered. As usual I am confused because I thought at least one of my catch blocks would be executed. My program output follows.</p>
  
  <pre><code>Main starting
  Hi There Received
  Hi There Received
  Hi There Received
  Jan 05, 2016 9:32:06 PM org.springframework.remoting.rmi.RmiProxyFactoryBean handleRemoteConnectFailure
  WARNING: Could not connect to RMI service [rmi://127.0.0.1:1099/Ping] - retrying
  Exception in thread "main" org.springframework.remoting.RemoteLookupFailureException: Lookup of RMI stub failed; nested exception is java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is: 
  java.net.ConnectException: Connection refused
  at org.springframework.remoting.rmi.RmiClientInterceptor.lookupStub(RmiClientInterceptor.java:215)
  at org.springframework.remoting.rmi.RmiClientInterceptor.refreshAndRetry(RmiClientInterceptor.java:326)
  at org.springframework.remoting.rmi.RmiClientInterceptor.handleRemoteConnectFailure(RmiClientInterceptor.java:307)
  at org.springframework.remoting.rmi.RmiClientInterceptor.invoke(RmiClientInterceptor.java:267)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
  at com.sun.proxy.$Proxy1.sayHello(Unknown Source)
  at com.edvs.main.TestIt.main(TestIt.java:34)
  Caused by: java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is: 
  java.net.ConnectException: Connection refused
  at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
  at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
  at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
  at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:342)
  at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
  at java.rmi.Naming.lookup(Naming.java:101)
  at org.springframework.remoting.rmi.RmiClientInterceptor.lookupStub(RmiClientInterceptor.java:200)
  ... 7 more
  Caused by: java.net.ConnectException: Connection refused
  at java.net.PlainSocketImpl.socketConnect(Native Method)
  at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
  at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
  at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
  at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
  at java.net.Socket.connect(Socket.java:589)
  at java.net.Socket.connect(Socket.java:538)
  at java.net.Socket.&lt;init&gt;(Socket.java:434)
  at java.net.Socket.&lt;init&gt;(Socket.java:211)
  at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
  at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148)
  at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
  ... 13 more
  </code></pre>
  
  <p>My code follows:</p>
  
  <pre><code>package com.edvs.main;
  import java.rmi.ConnectException;
  import java.rmi.RemoteException
  import org.springframework.context.ApplicationContext;
  import org.springframework.context.ConfigurableApplicationContext;
  import org.springframework.context.support.ClassPathXmlApplicationContext;
  import com.edvs.service.PingService;
  
  public class TestIt {
  
  public static void main(String[] args) {
  
      String file = "bean.xml";
      ApplicationContext context = null;
      try {
          context = new ClassPathXmlApplicationContext(file);
      } catch (Exception e) {
          System.out.println("exception:" + e.getMessage());
          System.exit(99);
      }
  
      System.out.println("Main starting");
      PingService ps = (PingService) context.getBean("pingBean");
      boolean done = false;
      int count = 30;
  
      if (ps != null) {
          while (!done &amp;&amp; count &gt; 0) {
              try {
                  if (ps.sayHello("Annapolis").equals("hi there")) {
                      System.out.println("Hi There Received");
                  }
              } catch (ConnectException ce) {
                  System.out.println("ConnectionException");
                  /*
                   * Something happened with the server so see if it is
                   * something we should retry the connection.
                   */
  
                  if (ce.getMessage().contains("Connection refused")) {
                      System.out.println("Connection Refused");
                  }
  
              } catch (RemoteException e) {
                  System.out.println("RemoteException:" + e.getMessage());
              }
              count--;
  
              try {
                  Thread.yield();
                  Thread.sleep(3000);
              } catch (InterruptedException e) {
                  done = true;
              }
          }
      }
  
      ((ConfigurableApplicationContext) context).close();
  
      System.out.println("Test has ended.");
    }
  }
  </code></pre>
  
  <p>bean.xml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
  xmlns:util="http://www.springframework.org/schema/util"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     http://www.springframework.org/schema/util
      http://www.springframework.org/schema/util/spring-util-2.5.xsd"&gt;
  
  
  &lt;bean id="pingBean" class="org.springframework.remoting.rmi.RmiProxyFactoryBean"&gt;
      &lt;property name="serviceUrl" value="rmi://127.0.0.1:1099/Ping" /&gt;
      &lt;property name="serviceInterface" value="com.edvs.service.PingService" /&gt;
      &lt;property name="refreshStubOnConnectFailure" value="true" /&gt;
      &lt;property name="lookupStubOnStartup" value="false" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p></p>
  
  <p>None of the exceptions are caught. The application just terminates. If I comment out refreshStubOnConnectFailure then the ConnectionException exception is thrown, but I don't know how to restart the connection once the server is restarted.</p>
  
  <p>For completeness and for others to gaze at, I am adding my final test code. It tests for the server initially and then continues to converse with the server.</p>
  
  <pre><code>package com.edvs.main;
  import java.net.MalformedURLException;
  import java.rmi.ConnectException;
  import java.rmi.Naming;
  import java.rmi.NotBoundException;
  import java.rmi.Remote;
  import java.rmi.RemoteException;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.springframework.context.ApplicationContext;
  import org.springframework.context.ConfigurableApplicationContext;
  import org.springframework.context.support.ClassPathXmlApplicationContext;
  import org.springframework.remoting.rmi.RmiProxyFactoryBean;
  
  import com.edvs.service.PingService;
  
  public class TestIt {
  static Log log = LogFactory.getLog(TestIt.class.getName());
  
  public static void main(String[] args) {
  
      String file = "bean.xml";
  
      ApplicationContext context = null;
      try {
          context = new ClassPathXmlApplicationContext(file);
      } catch (Exception e) {
          System.out.println("exception:" + e.getMessage());
          System.exit(99);
      }
  
      System.out.println("Main starting");
      log.info("foo");
  
      boolean done = false;
      int count = 30;
  
      RmiProxyFactoryBean rpfb = (RmiProxyFactoryBean) context.getBean("&amp;pingBean");
      String serviceUrl = rpfb.getServiceUrl();
  
      /*
       * See if the server is there as we startup.
       */
      while (true) {
          if (null != isServerThere(serviceUrl)) {
              /*
               * The server is there so continue with our processing.
               */
              break;
          } else {
              /*
               * The server is not there so sleep and then try again.
               */
              try {
                  Thread.yield();
                  Thread.sleep(3000);
              } catch (InterruptedException e) {
                  System.exit(33);
              }
          }
      }
  
      PingService ps = (PingService) context.getBean("pingBean");
  
      try {
          log.info("Service Name:" + ps.getServiceName());
          log.info("all:" + ps.toString());
          log.info("serviceUrl:" + rpfb.getServiceUrl());
  
      } catch (RemoteException e1) {
          // TODO Auto-generated catch block
          e1.printStackTrace();
      } catch (SecurityException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
  
      while (!done &amp;&amp; count &gt; 0) {
  
          try {
              if (ps.sayHello("Annapolis").equals("hi there")) {
                  log.info("Hi There Received");
              }
          } catch (ConnectException ce) {
              log.info("ConnectionException");
              /*
               * Something happened with the server so see if it is something we
               * should retry the connection.
               */
  
              if (ce.getMessage().contains("Connection refused")) {
                  log.info("Connection Refused");
                  ps = (PingService) isServerThere(serviceUrl);
              }
  
          } catch (RemoteException e) {
              System.out.println("RemoteException:" + e.getMessage());
          }
          count--;
  
          try {
              Thread.yield();
              Thread.sleep(3000);
          } catch (InterruptedException e) {
              done = true;
          }
      }
  
      ((ConfigurableApplicationContext) context).close();
  
      System.out.println("Test has ended.");
  }
  
  static private Remote isServerThere(String serviceUrl) {
      Remote remote = null;
  
      try {
          remote = Naming.lookup(serviceUrl);
  
      } catch (MalformedURLException | RemoteException | NotBoundException e) {
          log.error("Exception:" + e.getMessage());
      }
  
      return remote;
  }
  }
  </code></pre>