org.springframework.remoting.rmi
Class JndiRmiClientInterceptor

java.lang.Object
  extended by org.springframework.jndi.JndiAccessor
      extended by org.springframework.jndi.JndiLocatorSupport
          extended by org.springframework.jndi.JndiObjectLocator
              extended by org.springframework.remoting.rmi.JndiRmiClientInterceptor
All Implemented Interfaces:
Advice, Interceptor, MethodInterceptor, InitializingBean
Direct Known Subclasses:
JndiRmiProxyFactoryBean

public class JndiRmiClientInterceptor
extends JndiObjectLocator
implements MethodInterceptor, InitializingBean

Interceptor for accessing RMI services from JNDI. Typically used for RMI-IIOP (CORBA), but can also be used for EJB home objects (for example, a Stateful Session Bean home). In contrast to a plain JNDI lookup, this accessor also performs narrowing through PortableRemoteObject.

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.

The JNDI environment can be specified as jndiEnvironment property, or be configured in a jndi.properties file or as system properties. For example:

 <property name="jndiEnvironment">
         <props>
                 <prop key="java.naming.factory.initial">com.sun.jndi.cosnaming.CNCtxFactory</prop>
                 <prop key="java.naming.provider.url">iiop://localhost:1050</prop>
         </props>
 </property>

Since:
1.1
Author:
Juergen Hoeller
See Also:
JndiAccessor.setJndiTemplate(org.springframework.jndi.JndiTemplate), JndiAccessor.setJndiEnvironment(java.util.Properties), JndiObjectLocator.setJndiName(java.lang.String), JndiRmiServiceExporter, JndiRmiProxyFactoryBean, RemoteAccessException, RemoteException, Remote, PortableRemoteObject.narrow(java.lang.Object, java.lang.Class)

Field Summary
 
Fields inherited from class org.springframework.jndi.JndiLocatorSupport
CONTAINER_PREFIX
 
Fields inherited from class org.springframework.jndi.JndiAccessor
logger
 
Constructor Summary
JndiRmiClientInterceptor()
           
 
Method Summary
 void afterPropertiesSet()
          Check the jndiName property and initiate a lookup.
protected  Object doInvoke(MethodInvocation invocation, Remote stub)
          Perform the given invocation on the given RMI stub.
 Class getServiceInterface()
          Return the interface of the service to access.
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 setServiceInterface(Class serviceInterface)
          Set the interface of the service to access.
 
Methods inherited from class org.springframework.jndi.JndiObjectLocator
getJndiName, lookup, setJndiName
 
Methods inherited from class org.springframework.jndi.JndiLocatorSupport
convertJndiName, isResourceRef, lookup, setResourceRef
 
Methods inherited from class org.springframework.jndi.JndiAccessor
getJndiEnvironment, getJndiTemplate, setJndiEnvironment, setJndiTemplate
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

JndiRmiClientInterceptor

public JndiRmiClientInterceptor()
Method Detail

setServiceInterface

public void setServiceInterface(Class serviceInterface)
Set the interface of the service to access. The interface must be suitable for the particular service and remoting tool.

Typically required to be able to create a suitable service proxy, but can also be optional if the lookup returns a typed stub.


getServiceInterface

public Class getServiceInterface()
Return the interface of the service to access.


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

afterPropertiesSet

public void afterPropertiesSet()
                        throws NamingException
Description copied from class: JndiObjectLocator
Check the jndiName property and initiate a lookup.

The JNDI object will thus be fetched eagerly on initialization. For refreshing the JNDI object, subclasses can invoke lookup at any later time.

Specified by:
afterPropertiesSet in interface InitializingBean
Overrides:
afterPropertiesSet in class JndiObjectLocator
Throws:
NamingException
See Also:
JndiObjectLocator.lookup()

prepare

public void prepare()
             throws NamingException
Fetches RMI stub on startup, if necessary.

Throws:
NamingException - if thrown by JNDI API
See Also:
setLookupStubOnStartup(boolean), lookupStub()

lookupStub

protected Remote lookupStub()
                     throws NamingException
Create the RMI stub, typically by looking it up. Called on interceptor initialization if cacheStub is true; else called for each invocation by getStub().

Default implementation looks up the service URL via java.rmi.Naming. Can be overridden in subclasses.

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

getStub

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

Default implementation returns the stub created on initialization, if any; else, it invokes lookupStub to get a new stub for each invocation.

Can be overridden in subclasses, for example 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:
NamingException - if 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 on corresponding RMI exceptions.

Specified by:
invoke in interface MethodInterceptor
Throws:
Throwable
See Also:
getStub(), doInvoke(org.aopalliance.intercept.MethodInvocation, java.rmi.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. Default implementation delegates to RmiClientInterceptorUtils.

Parameters:
ex - the RMI exception to check
Returns:
whether the exception should be treated as connect failure
See Also:
RmiClientInterceptorUtils.isConnectFailure(java.rmi.RemoteException)

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


Copyright (c) 2002-2005 The Spring Framework Project.