TUSCANY-3850: Apply patch from Sebastian Millies to fix RMI bug: ConnectException after component restart

git-svn-id: https://svn.apache.org/repos/asf/tuscany/sca-java-1.x/trunk@1214198 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIReferenceInvoker.java b/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIReferenceInvoker.java
index d300cb7..66f3e5a 100644
--- a/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIReferenceInvoker.java
+++ b/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIReferenceInvoker.java
@@ -20,16 +20,19 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.rmi.ConnectException;
 import java.rmi.Remote;
+import java.rmi.UnexpectedException;
 
 import org.apache.tuscany.sca.host.rmi.RMIHost;
+import org.apache.tuscany.sca.invocation.DataExchangeSemantics;
 import org.apache.tuscany.sca.invocation.Invoker;
 import org.apache.tuscany.sca.invocation.Message;
-import org.apache.tuscany.sca.invocation.DataExchangeSemantics;
 
 /**
  * Invoker for RMI References.
- *
+ * 
  * @version $Rev$ $Date$
  */
 public class RMIReferenceInvoker implements Invoker, DataExchangeSemantics {
@@ -55,7 +58,7 @@
             Object[] args = msg.getBody();
             Object resp = invokeTarget(args);
             msg.setBody(resp);
-    
+
         } catch (InvocationTargetException e) {
             msg.setFaultBody(e.getCause());
         } catch (Throwable e) {
@@ -65,12 +68,49 @@
         return msg;
     }
 
-    public Object invokeTarget(final Object payload) throws InvocationTargetException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException {
+    public Object invokeTarget(final Object payload) throws InvocationTargetException, SecurityException,
+        NoSuchMethodException, IllegalArgumentException, IllegalAccessException {
+        // try cached proxy first
         if (proxy == null) {
             proxy = rmiHost.findService(host, port, svcName);
             // proxy = Naming.lookup(serviceURI);
         }
 
+        Object invocationResult = null;
+        InvocationTargetException rethrow = null;
+        try {
+            invocationResult = doInvokeTarget(payload);
+        } catch (InvocationTargetException e) {
+            // rethrow this exception from finally block unless it can be
+            // handled
+            rethrow = e;
+            // try to diagnose the error condition: proxy may be out-of-date
+            // (cf. TUSCANY-3850)
+            Throwable cause = e.getCause();
+            if (cause instanceof UndeclaredThrowableException) {
+                cause = cause.getCause();
+                if (cause instanceof UnexpectedException) {
+                    cause = cause.getCause();
+                    if (cause instanceof ConnectException) {
+                        // retry invoke with a fresh proxy
+                        rethrow = null;
+                        proxy = rmiHost.findService(host, port, svcName);
+                        invocationResult = doInvokeTarget(payload);
+                    }
+                }
+            }
+        } finally {
+            if (rethrow != null) {
+                throw rethrow;
+            }
+        }
+
+        return invocationResult;
+    }
+
+    private Object doInvokeTarget(final Object payload) throws InvocationTargetException, SecurityException,
+        NoSuchMethodException, IllegalArgumentException, IllegalAccessException {
+
         remoteMethod = proxy.getClass().getMethod(remoteMethod.getName(), remoteMethod.getParameterTypes());
 
         if (payload != null && !payload.getClass().isArray()) {