Pivotal Knowledge Base

Follow

RmiClientInterceptor Exception Occurs in a Spring Managed Application Under Load

Environment

 Product  Version
 Spring  All

Symptom

We access remote services via RMI. Intermittently throughout the day, we would receive RmiClientInterceptor exceptions. The server would fail to respond in a timely fashion. It tends to happen during high traffic/load. This explains what is causing the exception as well as presents a resolution, assuming, a standard RmiProxyFactoryBean is used on the client side and that the exception happens in the RmiClientInterceptor.lookupStub() method. This may indicate that the client side stub has become stale after the server becomes unavailable. In such events, ensure that the client generates a new stub rather than using the stale one.

Cause

While the re-registration of the target service usually happens automatically upon server restart, stubs held by clients become stale rather than being refreshed. Clients would not notice this unless they try to call a method on the stub again, which will result in a connect exception.

Resolution

To work around this, refreshStubOnConnectFailure property in RmiProxyFactoryBean exposes can be set so that a single retry invocation will be attempted automatically upon a connect exception.

Furthermore, if a more dynamic client, which attempts several reconnects after a RemoteLookupFailureException, is desired, the following should be implemented accordingly:

  if(!tryServiceInvocation(myService)){
    	retryServiceInvocation(10, myService);
    	}

    	private boolean tryServiceInvocation(MyServiceIntf myService) throws RemoteLookupFailureException {
    	try {
    	myService.doSomething(...);
    	} catch (RemoteLookupFailureException ex) {
    	//swallow exception but return false to notfiy of mishap
    	return false;
    	}
    	return true;
    	}

    	private void retryServiceInvocation(int times, MyServiceIntf myService) {
    	while(times > 0) {
    	try {
    	Thread.sleep(5000); //set the retry interval here
    	} catch (InterruptedException e) {
    	e.printStackTrace();
    	}

    	if(tryServiceInvocation(myService)) {
    	//invocation attempt successful so we can move on
    	continue;
    	}
    	times--;

Comments

Powered by Zendesk