org.springframework.remoting.rmi

## Class RmiClientInterceptor

- java.lang.Object
- - org.springframework.remoting.support.RemotingSupport
  - - org.springframework.remoting.support.RemoteAccessor
    - - org.springframework.remoting.support.UrlBasedRemoteAccessor
      - - org.springframework.remoting.support.RemoteInvocationBasedAccessor
        - - org.springframework.remoting.rmi.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`

- - ### Field Summary

    - ### Fields inherited from class org.springframework.remoting.support.RemotingSupport

      `logger`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `RmiClientInterceptor()`

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `afterPropertiesSet()` Invoked by a BeanFactory after it has set all bean properties supplied (and satisfied BeanFactoryAware and ApplicationContextAware).
    `protected Object` | `doInvoke(MethodInvocation invocation, Remote stub)` Perform the given invocation on the given RMI stub.
    `protected Object` | `doInvoke(MethodInvocation methodInvocation, RmiInvocationHandler invocationHandler)` Apply the given AOP method invocation to the given `RmiInvocationHandler`.
    `protected Remote` | `getStub()` Return the RMI stub to use.
    `Object` | `invoke(MethodInvocation invocation)` Fetches an RMI stub and delegates to `doInvoke`.
    `protected boolean` | `isConnectFailure(RemoteException ex)` Determine whether the given RMI exception indicates a connect failure.
    `protected Remote` | `lookupStub()` Create the RMI stub, typically by looking it up.
    `void` | `prepare()` Fetches RMI stub on startup, if necessary.
    `protected Object` | `refreshAndRetry(MethodInvocation invocation)` Refresh the RMI stub and retry the given invocation.
    `void` | `setCacheStub(boolean cacheStub)` Set whether to cache the RMI stub once it has been located.
    `void` | `setLookupStubOnStartup(boolean lookupStubOnStartup)` Set whether to look up the RMI stub on startup.
    `void` | `setRefreshStubOnConnectFailure(boolean refreshStubOnConnectFailure)` Set whether to refresh the RMI stub on connect failure.
    `void` | `setRegistryClientSocketFactory(RMIClientSocketFactory registryClientSocketFactory)` Set a custom RMI client socket factory to use for accessing the RMI registry.

    - ### Methods inherited from class org.springframework.remoting.support.RemoteInvocationBasedAccessor

      `createRemoteInvocation, getRemoteInvocationFactory, recreateRemoteInvocationResult, setRemoteInvocationFactory`

    - ### Methods inherited from class org.springframework.remoting.support.UrlBasedRemoteAccessor

      `getServiceUrl, setServiceUrl`

    - ### Methods inherited from class org.springframework.remoting.support.RemoteAccessor

      `getServiceInterface, setServiceInterface`

    - ### Methods inherited from class org.springframework.remoting.support.RemotingSupport

      `getBeanClassLoader, overrideThreadContextClassLoader, resetThreadContextClassLoader, setBeanClassLoader`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### 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(RMIClientSocketFactory registryClientSocketFactory)

      Set a custom RMI client socket factory to use for accessing the RMI registry.
      See Also:
        `RMIClientSocketFactory`, `LocateRegistry.getRegistry(String, int, RMIClientSocketFactory)`

    - #### afterPropertiesSet

          public void afterPropertiesSet()

      Description copied from interface: `InitializingBean`
      Invoked by a BeanFactory after it has set all bean properties supplied (and satisfied BeanFactoryAware and ApplicationContextAware).

      This method allows the bean instance to perform initialization only possible when all bean properties have been set and to throw an exception in the event of misconfiguration.

      Specified by:
        `afterPropertiesSet` in interface `InitializingBean`
      Overrides:
        `afterPropertiesSet` in class `UrlBasedRemoteAccessor`

    - #### prepare

          public void prepare()
                       throws RemoteLookupFailureException

      Fetches RMI stub on startup, if necessary.
      Throws:
        `RemoteLookupFailureException` - if RMI stub creation failed
      See Also:
        `setLookupStubOnStartup(boolean)`, `lookupStub()`

    - #### lookupStub

          protected 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 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()`

    - #### invoke

          public Object invoke(MethodInvocation invocation)
                        throws Throwable

      Fetches an RMI stub and delegates to `doInvoke`. If configured to refresh on connect failure, it will call `refreshAndRetry(org.aopalliance.intercept.MethodInvocation)` on corresponding RMI exceptions.
      Specified by:
        `invoke` in interface `MethodInterceptor`
      Throws:
        `Throwable`
      See Also:
        `getStub()`, `doInvoke(MethodInvocation, Remote)`, `refreshAndRetry(org.aopalliance.intercept.MethodInvocation)`, `ConnectException`, `ConnectIOException`, `NoSuchObjectException`

    - #### isConnectFailure

          protected boolean isConnectFailure(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

          protected Object refreshAndRetry(MethodInvocation invocation)
                                    throws 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:
        `Throwable` - in case of invocation failure
      See Also:
        `invoke(org.aopalliance.intercept.MethodInvocation)`

    - #### doInvoke

          protected Object doInvoke(MethodInvocation invocation,
                        Remote stub)
                             throws 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:
        `Throwable` - in case of invocation failure

    - #### doInvoke

          protected Object doInvoke(MethodInvocation methodInvocation,
                        RmiInvocationHandler invocationHandler)
                             throws RemoteException,
                                    NoSuchMethodException,
                                    IllegalAccessException,
                                    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:
        `RemoteException` - in case of communication errors
        `NoSuchMethodException` - if the method name could not be resolved
        `IllegalAccessException` - if the method could not be accessed
        `InvocationTargetException` - if the method invocation resulted in an exception
      See Also:
        `RemoteInvocation`