While developing an Stateless Session Bean for my Project, i encounter a problem.
My SB defines and initializes a class Variable (which is an object and global to every method in bean). Public/Private methods in the bean use this member variable and set diferent values , generally information or error messages to be display to Client, in it (as an collection).
Now my problem is that when i call the bean multiple times from the client (web browser in my case ,each time its a new request), after some requests my member variable is populated with old values (i.e values/messages developed as a result of previous request.) and my new request shows the previous messages from member variable.
Iam using Websphere 4.0 Application Server under Win2000 envirnoment.
So i just want to clarify the behaviour of class variable in case of stateless SB.
From section 24.1.2 (and first point) in the EJB 2.0 spec, it is clear that you are not allowed to write data to a class variable (although you can do it). (Normally, I recommend programmers in my projects to read that section early in the project. It contains important information, and is very well written.)
Moreover, I have the feeling that your code is stateful! This will be the case if you store error messages in a class (or instance) variable and make another call to the SB to get the error messags. Note that all instances of a stateless SB are equal, and this means you cannot store information (including error messages) in the stateless SB between client code calls to it. When your client code creates a stateless SB, you do not create a new bean instance on the server, you will just crate a thin object making it possible to access the bean. See the beginning of section 7.8 in the EJB 2.0 spec for details.
One solution to this problem is to store information in an instance variable (not a class variable) and make the bean stateful, but this is a potential preformance killer!
What I think you should do is to keep the bean stateless, and throw exceptions directly as an error occurs.
My understanding of what you have said is effectively the same. However, I have a slightly different question. If my client is making only one method call to my SSB (say to methodA), can I share object variables in that SSB between method calls in that bean eg. say methodA() calls methodB() which calls methodC(), etc. ie. can I be guaranteed that my object state will be correct across method calls within the bean.
I hope my question is clear.
From what I understand, your code will work exellent! The methodB() call will be on the same instance since it is equivalent to a this.methodB() call, and the JVM will execute methodB() on the same instance ("this").
First sentence in section 7.8.11 in the EJB 2.0 spec: "The container must ensure that only one thread can be executing an instance at any time." This means you cannot come to a situation where data (in yout instance variables) from different clients (threads) will be mixed. You are ensured unique access to the instance variables until mehtodA() has returned!
On the other hand: My personal opinion is that you should communicate data through argument list if methodA() calls methodB() on the same instance, instead of using an instance variable. Why:
Communicating data as arguments will simplify for other programmers reading and mainaining your code! Data flow will be more clear if data is in the argument list, while using instance variables will hide the data flow effectively. With hidden information channels (the instance variables), errors are likely to be introduced by other programmers later. (This is true for non-EJB code as well.)
And if methodB() is another business method (exposed in the remote interface), data must be communicated using the argument list! Otherwise, your bean will behave strange if methodB() is called directly by any other client code.
If mehtodB() is some simple utility method, this can be clearly pointed out by making methodB() private and static. (The "not static" requirement is section 7.10.4 is only true for "business methods", not for internal utility methods.)
When I am working as technical lead in projects I always point out that the code must be easy to understand (=easy to maintain) since all code is expected to be changed sooner or later. (This is not true if you are a consultant and want to ensure that the customer will need YOU for the next ten years...)
Tomas, consultant at Cap Gemini Ernst & Young
Note: I suppose stateless (and not stateful) is the interpretation of the first "S" is "SSB".
Thanks for clarifying for me. I think I will go with instance variables as I will make all "dependent" methods private, and only have one exposed "public" method.
On a slightly different note, I am note sure I agree with your preference to passing argument lists in non-ejb code. This is effectively what OO programming is all about. If we passed all required info via arg lists, then we may as well make the methods static, and we would effectively programming procedurally. Anyway, that is just my opinion.
Correct note! Of course, "real" instance variables (a property of the object of that class) should _not_ be passed as arguments between methods on the same object. What I don't like is the usage of instance variables for transfer of temporary data between methods. (I have no good examples now, but I expect one can find several of them in Swing UI programming.)
EJB - Argument passing semantics should be considered.
Thanks for all bunch of reply to my query and sorry for being late in the forum.
I am not keen upon the concept of Statefull bean, since I can't imagine what it would do to the application server if a batch of thousand messages arrives. WebSphere will attempt to create thousand instances of this bean. Moreover if we were to go for a state-ful bean these heavy Java-Classes/Bean (like one i am writting) would have to be loaded over and over again.
what to say?