diff options
Diffstat (limited to 'sca-java-2.x/trunk/modules/binding-rmi-runtime/src')
-rw-r--r-- | sca-java-2.x/trunk/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIBindingInvoker.java | 86 |
1 files changed, 65 insertions, 21 deletions
diff --git a/sca-java-2.x/trunk/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIBindingInvoker.java b/sca-java-2.x/trunk/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIBindingInvoker.java index 3cbc66f765..1bbcb49840 100644 --- a/sca-java-2.x/trunk/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIBindingInvoker.java +++ b/sca-java-2.x/trunk/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIBindingInvoker.java @@ -20,7 +20,10 @@ package org.apache.tuscany.sca.binding.rmi.provider; 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 java.security.AccessController; import java.security.PrivilegedAction; @@ -38,7 +41,7 @@ public class RMIBindingInvoker implements Invoker { private RMIHost rmiHost; private String uri; private Method remoteMethod; - // private Remote proxy; + private Remote proxy; public RMIBindingInvoker(RMIHost rmiHost, String uri, Method remoteMethod) { this.rmiHost = rmiHost; @@ -62,31 +65,73 @@ public class RMIBindingInvoker implements Invoker { return msg; } - public Object invokeTarget(final Object payload) throws InvocationTargetException, SecurityException, - NoSuchMethodException, IllegalArgumentException, IllegalAccessException { - Remote proxy = null; - final Class<?> remote = remoteMethod.getDeclaringClass(); - final ClassLoader stubClassLoader = remote.getClassLoader(); - // The generated remote interface is not available for the service lookup - final ClassLoader tccl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { - public ClassLoader run() { - ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(stubClassLoader); - return tccl; - } - }); + public Object invokeTarget(final Object payload) throws InvocationTargetException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException { + + if (proxy == null) { + initProxy(); + } + + Object invocationResult = null; + InvocationTargetException rethrow = null; try { - // The proxy cannot be cached as the remote services can be rebound - proxy = rmiHost.findService(uri); + 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(uri); + invocationResult = doInvokeTarget(payload); + } + } + } } finally { - AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { + if (rethrow != null) { + throw rethrow; + } + } + + return invocationResult; + } + + private synchronized void initProxy() { + if (proxy == null) { + final Class<?> remote = remoteMethod.getDeclaringClass(); + final ClassLoader stubClassLoader = remote.getClassLoader(); + // The generated remote interface is not available for the service + // lookup + final ClassLoader tccl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { public ClassLoader run() { - ClassLoader current = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(tccl); - return current; + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(stubClassLoader); + return tccl; } }); + try { + // The proxy cannot be cached as the remote services can be rebound + proxy = rmiHost.findService(uri); + } finally { + AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { + public ClassLoader run() { + ClassLoader current = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(tccl); + return current; + } + }); + } } + } + + private Object doInvokeTarget(final Object payload) throws InvocationTargetException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException { remoteMethod = proxy.getClass().getMethod(remoteMethod.getName(), remoteMethod.getParameterTypes()); @@ -96,5 +141,4 @@ public class RMIBindingInvoker implements Invoker { return remoteMethod.invoke(proxy, (Object[])payload); } } - } |