I am writing an application that uses RMI to invoke EJBs. The EJBs are Stateless; the business requirements do not require conversational state with the client.
One of the parameters to the EJB method calls is a "User" object used to determine if the user associated with the call has permission to perform the action. We are not using container-managed auth-auth: the User object is just a POJO provided by the remote client.
I would like to make this User object globally available/injectable within the "session" or invocation context. I am aware that Stateless EJBs do not have a "session" in the EJB sense; what I mean by "session" is "the current invocation". For example, say we have only one remote EJB with two methods:
myStatelessEjb.add(Thing, User)
myStatelessEjb.update(Thing, User)
These methods call many more methods: there are other EJBs involved, Bean Validators, etc. Rather than passing-around the User object everywhere, I would like to make the User object globally available/injectable with the context of the current remote EJB invocation.
I could of course just pass around the User object or encapsulate it with "Thing", but I thought maybe it would be a better design to not "pollute" my objects and APIs with User since it's a cross-cutting concern.
Notes (for emphasis):
- I am using RMI.
- There is no HTTP session, because I am using RMI.
- I am not using container-managed auth-auth.
- I am using container-managed transactions.
Is there a standard technique suitable for this problem? e.g. Perhaps the remote client should invoke a Stateful EJB which will hold the User, or maybe ThreadLocal is appropriate, or maybe I can hook onto the container-managed transaction, or maybe there's already an applicable session/context I'm unaware of.
Easiest way would be to store the user in a @RequestScoped CDI bean and inject that as required:
While
@SessionScoped
is useful for HTTP sessions only,@RequestScoped
has broader applicability: