Jul 3rd, 2007, 06:22 AM
Race condition during RMI services startup and client calls
Does anyone have any suggestions on how to best handle the following?
1) RMI services exported using the RMIServicesExporter
2) client using the RmiProxyFactoryBean
The client is constantly calling the server. The server is bounced. setRefreshStubOnConnectFailure is set to true on the client proxy factory.
- When the server goes down, the client notices and logs the following, as expected:
WARN [org.springframework.remoting.rmi.RmiProxyFactoryBe an] Could not connect to RMI service [rmi://SERVERNAME:PORT/serviceName] - retrying
- The RMI registry becomes available, but the "serviceName" service is not yet registered:
org.springframework.remoting.RemoteLookupFailureEx ception: RMI lookup for service [rmi://SERVERNAME:PORT/serviceName] failed; nested exception is org.springframework.remoting.RemoteLookupFailureEx ception: Could not find RMI service [rmi://SERVERNAME:PORT/serviceName] in RMI registry; nested exception is java.rmi.NotBoundException: serviceName
- After the service is registered, all calls on the client side throw:
org.springframework.remoting.RemoteProxyFailureExc eption: Failed to invoke RMI stub for remote service [rmi://SERVERNAME:PORT/serviceName]; nested exception is java.lang.NoSuchMethodException: $Proxy50.someMethodName(java.lang.Integer, java.lang.Integer)
java.lang.NoSuchMethodException: $Proxy50.someMethodName(java.lang.Integer, java.lang.Integer)
at org.springframework.remoting.support.RemoteInvocat ion.invoke(RemoteInvocation.java:178)
at org.springframework.remoting.support.DefaultRemote InvocationExecutor.invoke(DefaultRemoteInvocationE xecutor.ja
In other words, the client stubs don't notice that the services are back up and they're stuck in this state until the client is re-initialised (either by bouncing the server and missing the race condition by luck, or by bouncing the client and properly re-connecting to the RMI registry with services available).
So, can the client proxies be made any smarter? I'd considered putting an aspect around our client stubs to catch this kind of exception and attempt to re-connect, similar to the current behaviour when setRefreshStubOnConnectFailure == true, but this almost seems like it would be a worthwhile feature to add to the RmiProxyFactoryBean (something like setRefreshStubOnServiceLookupFailure).
Jul 3rd, 2007, 07:16 AM
I suggest to file a report to Jira. If you could also attach a small test to reproduce the problem, that would be very helpful.
Jul 3rd, 2007, 01:18 PM
Thanks Andreas, I've opened SPR-3643 for this. Unfortunately, the exact test case is a little tricky to reproduce (it's all timing luck). I haven't got the bandwidth at the moment to work out how to create the RMI registry first, create a client (that bombs) then add the services (but that's what the test case would be....).