The EJBClient invocation mechanism makes use of affinities (strong affinity, weak affinity) when choosing a target node to send an invocation to. The combination of strong and weak affinity places constraints on choice of node, from among all of those that are available. For example, we may want a proxy to direct all invocations to a particular cluster: the strong affinity would reflect the cluster name. The weak affinity may vary depending on the type of bean: for a SFSB, we want the invocation to be directed to the node within the cluster on which the session was originally created (NodeAffinity(<session node>)); for a SLSB, we may not care which node in the cluster the invocation is sent to (Affinity.NONE).
Strong affinity is held in the EJBLocator associated with the proxy and does not change over the lifetime of the proxy. Weak affinity is held in the EJBInvocationHandler associated with the proxy and may change over the lifetime of the proxy (for example, if a cluster node fails and invocations need to be directed to another node in the cluster).
The invocation mechanism uses EJBClientContext.performLocatedAction(EJBLocator locator, LocatedAction action) to choose a target node which is consistent with the locator affinity, and execute the action on that node. As an intermediate step, the choice of target is represented as a triple: <EJBReceiver receiver, EJBLocator locator, Affinity newAffinity> and the action uses this triple to execute the action:
The issue is that the choice of target is being made solely on the basis of the strong affinity of the EJBLocator, and the weak affinity in the EJBInvocationHandler is not considered (although it is updated post-invocation). This means that we may have a proxy with strong affinity "ejb" and weak affinity "node1", but invocations may be directed to nodes in the cluster other than "node1".