org.springframework.remoting.rmi

Class RmiClientInterceptor

  • All Implemented Interfaces:
    Advice, Interceptor, MethodInterceptor, Aware, BeanClassLoaderAware, InitializingBean
    Direct Known Subclasses:
    RmiProxyFactoryBean


    public class RmiClientInterceptor
    extends RemoteInvocationBasedAccessor
    implements MethodInterceptor
    MethodInterceptor for accessing conventional RMI services or RMI invokers. The service URL must be a valid RMI URL (e.g. "rmi://localhost:1099/myservice").

    RMI invokers work at the RmiInvocationHandler level, needing only one stub for any service. Service interfaces do not have to extend java.rmi.Remote or throw java.rmi.RemoteException. Spring's unchecked RemoteAccessException will be thrown on remote invocation failure. Of course, in and out parameters have to be serializable.

    With conventional RMI services, this invoker is typically used with the RMI service interface. Alternatively, this invoker can also proxy a remote RMI service with a matching non-RMI business interface, i.e. an interface that mirrors the RMI service methods but does not declare RemoteExceptions. In the latter case, RemoteExceptions thrown by the RMI stub will automatically get converted to Spring's unchecked RemoteAccessException.

    Since:
    29.09.2003
    Author:
    Juergen Hoeller
    See Also:
    RmiServiceExporter, RmiProxyFactoryBean, RmiInvocationHandler, RemoteAccessException, RemoteException, Remote
    • Constructor Detail

      • RmiClientInterceptor

        public RmiClientInterceptor()
    • Method Detail

      • setLookupStubOnStartup

        public void setLookupStubOnStartup(boolean lookupStubOnStartup)
        Set whether to look up the RMI stub on startup. Default is "true".

        Can be turned off to allow for late start of the RMI server. In this case, the RMI stub will be fetched on first access.

        See Also:
        setCacheStub(boolean)
      • setCacheStub

        public void setCacheStub(boolean cacheStub)
        Set whether to cache the RMI stub once it has been located. Default is "true".

        Can be turned off to allow for hot restart of the RMI server. In this case, the RMI stub will be fetched for each invocation.

        See Also:
        setLookupStubOnStartup(boolean)
      • setRefreshStubOnConnectFailure

        public void setRefreshStubOnConnectFailure(boolean refreshStubOnConnectFailure)
        Set whether to refresh the RMI stub on connect failure. Default is "false".

        Can be turned on to allow for hot restart of the RMI server. If a cached RMI stub throws an RMI exception that indicates a remote connect failure, a fresh proxy will be fetched and the invocation will be retried.

        See Also:
        ConnectException, ConnectIOException, NoSuchObjectException
      • setRegistryClientSocketFactory

        public void setRegistryClientSocketFactory(java.rmi.server.RMIClientSocketFactory registryClientSocketFactory)
        Set a custom RMI client socket factory to use for accessing the RMI registry.
        See Also:
        RMIClientSocketFactory, LocateRegistry.getRegistry(String, int, RMIClientSocketFactory)
      • lookupStub

        protected java.rmi.Remote lookupStub()
                                      throws RemoteLookupFailureException
        Create the RMI stub, typically by looking it up.

        Called on interceptor initialization if "cacheStub" is "true"; else called for each invocation by getStub().

        The default implementation looks up the service URL via java.rmi.Naming. This can be overridden in subclasses.

        Returns:
        the RMI stub to store in this interceptor
        Throws:
        RemoteLookupFailureException - if RMI stub creation failed
        See Also:
        setCacheStub(boolean), Naming.lookup(java.lang.String)
      • getStub

        protected java.rmi.Remote getStub()
                                   throws RemoteLookupFailureException
        Return the RMI stub to use. Called for each invocation.

        The default implementation returns the stub created on initialization, if any. Else, it invokes lookupStub() to get a new stub for each invocation. This can be overridden in subclasses, for example in order to cache a stub for a given amount of time before recreating it, or to test the stub whether it is still alive.

        Returns:
        the RMI stub to use for an invocation
        Throws:
        RemoteLookupFailureException - if RMI stub creation failed
        See Also:
        lookupStub()
      • isConnectFailure

        protected boolean isConnectFailure(java.rmi.RemoteException ex)
        Determine whether the given RMI exception indicates a connect failure.

        The default implementation delegates to RmiClientInterceptorUtils.isConnectFailure(java.rmi.RemoteException).

        Parameters:
        ex - the RMI exception to check
        Returns:
        whether the exception should be treated as connect failure
      • refreshAndRetry

        @Nullable
        protected java.lang.Object refreshAndRetry(MethodInvocation invocation)
                                                      throws java.lang.Throwable
        Refresh the RMI stub and retry the given invocation. Called by invoke on connect failure.
        Parameters:
        invocation - the AOP method invocation
        Returns:
        the invocation result, if any
        Throws:
        java.lang.Throwable - in case of invocation failure
        See Also:
        invoke(org.aopalliance.intercept.MethodInvocation)
      • doInvoke

        @Nullable
        protected java.lang.Object doInvoke(MethodInvocation invocation,
                                                      java.rmi.Remote stub)
                                               throws java.lang.Throwable
        Perform the given invocation on the given RMI stub.
        Parameters:
        invocation - the AOP method invocation
        stub - the RMI stub to invoke
        Returns:
        the invocation result, if any
        Throws:
        java.lang.Throwable - in case of invocation failure
      • doInvoke

        @Nullable
        protected java.lang.Object doInvoke(MethodInvocation methodInvocation,
                                                      RmiInvocationHandler invocationHandler)
                                               throws java.rmi.RemoteException,
                                                      java.lang.NoSuchMethodException,
                                                      java.lang.IllegalAccessException,
                                                      java.lang.reflect.InvocationTargetException
        Apply the given AOP method invocation to the given RmiInvocationHandler.

        The default implementation delegates to RemoteInvocationBasedAccessor.createRemoteInvocation(org.aopalliance.intercept.MethodInvocation).

        Parameters:
        methodInvocation - the current AOP method invocation
        invocationHandler - the RmiInvocationHandler to apply the invocation to
        Returns:
        the invocation result
        Throws:
        java.rmi.RemoteException - in case of communication errors
        java.lang.NoSuchMethodException - if the method name could not be resolved
        java.lang.IllegalAccessException - if the method could not be accessed
        java.lang.reflect.InvocationTargetException - if the method invocation resulted in an exception
        See Also:
        RemoteInvocation