Announcement Announcement Module
No announcement yet.
no re-connect to SLSB after application server restart Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • no re-connect to SLSB after application server restart


    We had problems with the re-connect feature of SimpleRemoteStatelessSessionProxyFactoryBean: restarting the application server (WebSphere 5.1) hosting the SLSB caused the client proxy to that SLSB to become stale and did not trigger a re-lookup of the Home Interface of the SLSB (aka re-connect). The result was, that the client kept receiving RemoteExceptions even after the application server was up again.

    Referring to the source of Spring 1.1.3:
    The re-connect decision is made in AbstractRemoteSlsbInvokerInterceptor.invoke() with the help of RmiClientInterceptorUtils.isConnectFailure(): ConnectException, ConnectIOException and NoSuchObjectException (all sub-classes of RemoteException) trigger a re-connect, all other RemoteExceptions don't. In our case, after the restart of the application server, a MarshalException (also a sub-classes of RemoteException) was thrown to the client, which consequently did not trigger a re-connect.

    Why be so restrictive on the RemoteExceptions that cause a re-connect? Probably because if a SLSB method throws a RuntimeException (system exception) this is re-thrown as a RemoteException to the client and we don't in general want such a case to result in a re-connect (which would cause the method to be executed again).

    (In our case, we simply treated all RemoteExceptions as a sign to attempt a re-connect because our SLSB methods were idempotent.)

    The least one could do is to be more complete (in RmiClientInterceptorUtils.isConnectFailure()) in the sub-classes of RemoteException that trigger a re-connect:


  • #2
    Hi Gerald,

    Good point - the actual RemoteExceptions thrown by different application servers might vary, in particular regarding connect failures. Unfortunately, there is no standard exception to be thrown by EJB containers in such a case...

    The problem is that a RemoteException thrown by an EJB proxy can indicate all sorts of things. It can be a RemoteException thrown by the EJB implementation on the server, a failed transaction on the server, a communication error, or a configuration error on the client. We wouldn't want to perform a full reconnect for each of those; that's why we filter for specific exceptions that indicate a connect failure.

    (The EJB spec should really define exceptions in a more fine-grained fashion... Why do communication errors and failed transactions lead to the same exception class - not even to specific standard subclasses?)

    I've reworked RmiClientInterceptorUtils to also trigger a connect failure on UnknownHostException, StubNotFoundException, MarshalException and UnmarshalException. ServerError, ServerException and UnexpectedException just indicate exceptions thrown on the server during execution there, so should not trigger a connect failure, IMO.



    • #3
      java.rmi.ConnectException vs.

      Spring catches java.rmi.ConnectException.

      Our client and server both run in WebSphere WAS, and both use Spring. When the server goes down and our client code calls an EJB there, WAS throws a Note the package difference. is a subclass of SocketException, not RemoteException.

      I pinged IBM on this, and they feel they're throwing the right Exception. As Juergen says, app server vendors are pretty much free to throw whatever they want.

      Could RmiClientInterceptorUtils.isConnectFailure() recognize too? The description of looks very specific to exactly the situation that isConnectFailure() is intended to recognize. It would make Spring more compatible with WebSphere WAS (at least in the 5.1 release!).



      • #4
        Manual reconnect?

        Is there any way to force the SLSB proxy to re-connect programmatically?

        As noted, there may be exceptions that require a re-connect that aren't handled by Spring proxy code - possibly due to vendor-specific implementations. There may also be other reasons to explicitly refresh the home (e.g. to switch to a different EJB server without a bounce).

        There is a "refreshHome" method on the proxy, but it's protected. Is there another way to do this?


        • #5
          Even though no one has replied I thought I'd post about what I did to resolve this - create an SLSB invoker which would allow configuration of additional "connection failure" exceptions.

          This SimpleRemoteSlsbInvokerInterceptor subclass just adds a property - a Set of addtional exception names - and overrides isConnectFailure(). The new isConnectFailure() delegates to the superclass' implementation, but will also check against the configured Set of exception names if the superclass returns false (no connection failure).

          This way we can easily maintain a custom list of additional "connection failure" exceptions in our Spring XML files.


          • #6
            Did you have to modify Spring source code to create this custom SLSB invoker or did you plug this custom SLSB using Spring configuration.

            If so, can you still use the specific tag jee:remote-slsb or do you need to use the classic bean tag?

            Thank you,


            • #7
              The invoker itself is just a subclass; no modifications necessary to the base Spring class. This app uses an older version of Spring so the config uses the generic bean tag. There's probably a way to make the new-fangled tags use a custom invoker, but I haven't looked into that (and I'm not working on that particular project anymore either).