My EJB client program needs to call EJB (stateless session bean) with one username and then the same EJB again, but with another user name.
At client side, I created new InitialContext(Envionment), where the Environment is a property which contains user name. And, in my EJB, I store the sessionContext as a member variable in setSessionContext() callback.
However, I noticed that when I call EJB for the 2nd time, the user name returned from sessionContext.getCallerPrincipal() is still the 1st user name.
In addition, even though the EJB is called twice, setSessionContext() is called only once.
Is there a way to make sessionContext reflect user credential as they change at run-time?
I cannot answer your question but I can shed some light into why setSessionContext() is only called once. As you may recall a Stateless Session Bean (SLSB) does not have a state and therefore the container can pool the instances for the clients to use. In addition the setSessionContext() is only called once when an SLSB is created meaning when the pool needs a new instance. From that point on the pool will return a free instance, create a new one (if possible) or block until an instance becomes available. Because you called the SLSB in serie there is only one instance created within the pool and so the second call is (re)using the first instance.
Andy's description is basically correct, at least until right at the end were I think it is hinting at a final conclusion that isn't correct.
No matter how many instances of an SLSB you have initialized in a pool, getCallerPrincipal() will never be forced to be a fixed value. The SessionContext is effectively a facade object around access points for container services. Each time you invoke methods on that context you get the values or behaviours that make sense right now, not the ones that made sense at the time the object was created and setSessionContext invoiked.
If you think about it, this has to be the case, and the specific case of SLSB shows why. Those objects were probably put into the pool even before *any* client existed, during some part of the deployment and application initialization, so there was no possible value yet for getCallerPrincipal. There is no client during setSessionContext and ejbCreate. You don't know the client until business method invocation. As long as you don't make the mistake of caching values in the SLSB that could change at runtime (like an actual principal), you'll always get correct invocation-context-specific behaviour from the container services.
We don't know how Yan Zhou's client program does what it does, if it is internal to the container or external to it, etc., but at a quick guess it sounds a lot more like either a JNDI or JAAS problem, or perhaps a transaction problem, but not as likely any kind of EJB problem. The most likely specific issue that comes to mind would be something like keeping an object stub obtained from the first JNDI authenticated connection, and expecting to somehow shift its security perms after opening a second JNDI authenticated connection. If the RMI stub has the original authentication info cached in it, the EJB caller principal would continue to reflect the perms of the original connection. [ March 14, 2006: Message edited by: Reid M. Pinchback ]