Class JndiRmiClientInterceptor
- java.lang.Object
- org.springframework.jndi.JndiAccessor
- org.springframework.jndi.JndiLocatorSupport
- org.springframework.jndi.JndiObjectLocator
- org.springframework.remoting.rmi.JndiRmiClientInterceptor
- All Implemented Interfaces:
Advice
,Interceptor
,MethodInterceptor
,InitializingBean
- Direct Known Subclasses:
JndiRmiProxyFactoryBean
public class JndiRmiClientInterceptor extends JndiObjectLocator implements MethodInterceptor, InitializingBean
MethodInterceptor
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
,javax.rmi.PortableRemoteObject#narrow
Field Summary
Fields inherited from class org.springframework.jndi.JndiLocatorSupport
CONTAINER_PREFIX
Fields inherited from class org.springframework.jndi.JndiAccessor
logger
Constructor Summary
Constructors Constructor Description JndiRmiClientInterceptor()
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
afterPropertiesSet()
Invoked by the containingBeanFactory
after it has set all bean properties and satisfiedBeanFactoryAware
,ApplicationContextAware
etc.protected RemoteInvocation
createRemoteInvocation(MethodInvocation methodInvocation)
Create a new RemoteInvocation object for the given AOP method invocation.protected Object
doInvoke(MethodInvocation invocation, Object 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 givenRmiInvocationHandler
.RemoteInvocationFactory
getRemoteInvocationFactory()
Return the RemoteInvocationFactory used by this accessor.Class<?>
getServiceInterface()
Return the interface of the service to access.protected Object
getStub()
Return the RMI stub to use.Object
invoke(MethodInvocation invocation)
Fetches an RMI stub and delegates todoInvoke(org.aopalliance.intercept.MethodInvocation, java.lang.Object)
.protected boolean
isConnectFailure(RemoteException ex)
Determine whether the given RMI exception indicates a connect failure.protected boolean
isConnectFailure(SystemException ex)
Determine whether the given CORBA exception indicates a connect failure.protected Object
lookupStub()
Create the RMI stub, typically by looking it up.void
prepare()
Fetches the 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
setExposeAccessContext(boolean exposeAccessContext)
Set whether to expose the JNDI environment context for all access to the target RMI stub, i.e.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
setRemoteInvocationFactory(RemoteInvocationFactory remoteInvocationFactory)
Set the RemoteInvocationFactory to use for this accessor.void
setServiceInterface(Class<?> serviceInterface)
Set the interface of the service to access.Methods inherited from class org.springframework.jndi.JndiObjectLocator
getExpectedType, getJndiName, lookup, setExpectedType, setJndiName
Methods inherited from class org.springframework.jndi.JndiLocatorSupport
convertJndiName, isResourceRef, lookup, lookup, setResourceRef
Methods inherited from class org.springframework.jndi.JndiAccessor
getJndiEnvironment, getJndiTemplate, setJndiEnvironment, setJndiTemplate
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.
setRemoteInvocationFactory
public void setRemoteInvocationFactory(RemoteInvocationFactory remoteInvocationFactory)
Set the RemoteInvocationFactory to use for this accessor. Default is aDefaultRemoteInvocationFactory
.A custom invocation factory can add further context information to the invocation, for example user credentials.
getRemoteInvocationFactory
public RemoteInvocationFactory getRemoteInvocationFactory()
Return the RemoteInvocationFactory used by this accessor.
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.
setExposeAccessContext
public void setExposeAccessContext(boolean exposeAccessContext)
Set whether to expose the JNDI environment context for all access to the target RMI stub, i.e. for all method invocations on the exposed object reference.Default is "false", i.e. to only expose the JNDI context for object lookup. Switch this flag to "true" in order to expose the JNDI environment (including the authorization context) for each RMI invocation, as needed by WebLogic for RMI stubs with authorization requirements.
afterPropertiesSet
public void afterPropertiesSet() throws NamingException
Description copied from interface:InitializingBean
Invoked by the containingBeanFactory
after it has set all bean properties and satisfiedBeanFactoryAware
,ApplicationContextAware
etc.This method allows the bean instance to perform validation of its overall configuration and final initialization when all bean properties have been set.
- Specified by:
afterPropertiesSet
in interfaceInitializingBean
- Overrides:
afterPropertiesSet
in classJndiObjectLocator
- Throws:
NamingException
prepare
public void prepare() throws RemoteLookupFailureException
Fetches the RMI stub on startup, if necessary.- Throws:
RemoteLookupFailureException
- if RMI stub creation failed- See Also:
setLookupStubOnStartup(boolean)
,lookupStub()
lookupStub
protected Object 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 retrieves the service from the JNDI environment. 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)
,JndiObjectLocator.lookup()
getStub
protected Object getStub() throws NamingException, 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:
NamingException
- if stub creation failedRemoteLookupFailureException
- if RMI stub creation failed
invoke
public Object invoke(MethodInvocation invocation) throws Throwable
Fetches an RMI stub and delegates todoInvoke(org.aopalliance.intercept.MethodInvocation, java.lang.Object)
. If configured to refresh on connect failure, it will callrefreshAndRetry(org.aopalliance.intercept.MethodInvocation)
on corresponding RMI exceptions.- Specified by:
invoke
in interfaceMethodInterceptor
- Parameters:
invocation
- the method invocation joinpoint- Returns:
- the result of the call to
Joinpoint.proceed()
; might be intercepted by the interceptor - Throws:
Throwable
- if the interceptors or the target object throws an exception- See Also:
getStub()
,doInvoke(org.aopalliance.intercept.MethodInvocation, java.lang.Object)
,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
isConnectFailure
protected boolean isConnectFailure(SystemException ex)
Determine whether the given CORBA exception indicates a connect failure.The default implementation checks for CORBA's
org.omg.CORBA.OBJECT_NOT_EXIST
exception.- 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, Object stub) throws Throwable
Perform the given invocation on the given RMI stub.- Parameters:
invocation
- the AOP method invocationstub
- 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 givenRmiInvocationHandler
.The default implementation delegates to
createRemoteInvocation(org.aopalliance.intercept.MethodInvocation)
.- Parameters:
methodInvocation
- the current AOP method invocationinvocationHandler
- the RmiInvocationHandler to apply the invocation to- Returns:
- the invocation result
- Throws:
RemoteException
- in case of communication errorsNoSuchMethodException
- if the method name could not be resolvedIllegalAccessException
- if the method could not be accessedInvocationTargetException
- if the method invocation resulted in an exception- See Also:
RemoteInvocation
createRemoteInvocation
protected RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation)
Create a new RemoteInvocation object for the given AOP method invocation.The default implementation delegates to the configured
RemoteInvocationFactory
. This can be overridden in subclasses in order to provide custom RemoteInvocation subclasses, containing additional invocation parameters (e.g. user credentials).Note that it is preferable to build a custom RemoteInvocationFactory as a reusable strategy, instead of overriding this method.
- Parameters:
methodInvocation
- the current AOP method invocation- Returns:
- the RemoteInvocation object
- See Also:
RemoteInvocationFactory.createRemoteInvocation(org.aopalliance.intercept.MethodInvocation)