It seems to me that the J2EE platform has two competing solutions for storing client state: Stateful session beans and HttpSession parameters.
Most architectures I've encountered choose to use stateless session beans and store the client's state in the web layer's HttpSession.
The advantage is that the JSP layer doesn't have to message a session bean to get its state and stateless session beans are widely documented as scaling better than stateful ones.
However, stateful session beans are architected for just this purpose. As containers get more sophisticated, it seems to me that the stateful session bean could be a lot more efficient at caching state than HttpSession.
For example, in the 2.0 EJB spec, it mentions that the EJB container VM could be smart enough to map the beans state from memory directly to disk [during passivation], avoiding the overhead of serialization.
So, in the long run, having the web layer stateless may be more scalable than having the session layer stateless.
Look at the Sun J2EE PetShop example. If I'm right, they use stateful EJB for keeping session information. They also discuss the reason WHY they use EJB and not HTTP Session.
You may want to use a stateful session bean to track the
state of a particular transaction. i.e some one buying a
the web Session tracks the state of where the user is in
the html page flow. However, if the user then gained access
to the system through a different channel e.g a wap phone,
or through a call centre you would still want to know the state of the ticket buying transaction.
I agree with you.
One of the most difficult thinks in the OO world is to give the right role to the right object.
Using Stateful session Beans is relevant when you need a "state machine" for your business logic, and it's is independent from how you "interact" with the system (WAP/WML, HTML, XML/B2B, etc).
HTTP session is for objects that drive the "application". It provides "state machine" for presentation logic.
We can write truly reusable objects on both sides. Just give them the right responsabilities.
sorry about my poor english
Your English does'nt matter, as far as you give the right and valuable information. Anyway thanks for the info you have provided.
Your English does'nt matter, as far as you give the right and valuable information. Anyway thanks for the info you have provided.
The Servlet/JSP tier should be used for presentation logic (UI generation, validation, navigation etc). The EJB tier should be used for business logic.
Accordingly: Use the HttpSession for storing presentation logic state and use stateful session EJBs for business logic state.
This separation of responsibility is probably more intuitive by comparing HTML/Servlet/JSP to a pure Java or Windows client. A fat client would contain all the presentation logic (validation, navigation etc) in the client tier, calling EJBs directly.
In the purest sense of this topic, I would definitely agree with you. However, when you have a web server trying to keep track of all the states for thousands of clients, you have to start looking at resource management. Unfortuantely web servers have not advanced as fast as application servers in overall resource management.
I ran into problems of our web server trying to keep track of all these client sessions in memory. The web server would just freeze and you could not do anything. I moved the session's state into a stateful session bean because it seemed like WebLogic (the EJB container) could better manage the resources needed to keep track of these sessions, especially in the way it handles passivating components and writing out their state disk. I know it is really keeping the state of a client session, but the web server does not have the capability to handle resources like an app server. I still have stateless session beans that handle my core business logic and they scale very well. The overall end result is I don't get hang ups anymore with the web server because it is acting as a traffic cop for making request and keeping the presentation logic in JSPs. I do take a little hit on having to go to this extra session bean to determine my state, but the net effect has been positive.
Sun put the business work flow into Stateful session bean.
Business work flow is a state machine ( can't use stateless
bean for state machine because it has to remember the states). The reason is clear , they want to make the business work flow independent of presentation logic.
This is very important if you also have client other than
The problem we have is that Stateful session has time-out and when that happens, state will be lost.
Any thoughts on how to solve this other than keeping session
or business state in servlet ?
There's an interesting issue with respect to timeout. If navigational state etc. is stored in the HttpSession and some other state is in stateful session beans, here's a possible problem scenario (if I missed something, please tell me):
A user logs on to the system and does something that involves creating and using a stateful session bean. Then the user moves around for a while using functionality that does not touch the bean, thus repeatedly resetting the timeout of the HttpSession. It is then possible that the next time the user triggers a function that involves the bean, it may have timed out. The user of course expects his session to be far from timed out, since he's been working all the time. So he will not be very happy if the system tells him that, "sorry, you will have to log in again".
The only solution I can see to this problem would be to set the bean timeout so high that the situation is unlikely to happen (though this would not solve the problem in theory). Any other way involves doing "unnecessary" remote calls in some kind of "heartbeat" scheme. The best solution is maybe to avoid stateful session beans except in scenarios where the bean is guaranteed to be accessed in every request (but would such a scenario ever be desirable?).
I am developing an application that allows users query a huge resultset. The size of the resultset could be over 3000+ rows of data. (I tried to serialize the data to disk. It is about 1.3MB - 2MB). However, we can always show a limit of row per page. Therefore, I will need to store the resultset somewhere. I was thinking about HttpSession but it may be too much.(I am using weblogic, and the data of session will be replicated to a secondary server to provide failover and load-balancing). Copying 2MB data per request may be too expensive. Should I use stateful bean to handle this? Or is there any better way to handle this problem? I was thinking using rownum to limit the data per request but the data of this application can be changed any seconds. Therefore, I will need to cache the original resultset.
I appreciate any helps
Instead of retrieving all the 3000 rows at one time and try to save it in memory, why don't you retrieve only the information needed for a single page? In your stateful session bean, you can keep track of which page the user is on and when user choose either next page, previous page, you can run a much smaller query to retrieve just the amount of data needed for that page from database.
Actually, if you set timeout as zero, the SFSB won't be timed out. Hope this helps.
Have you successfully implemented SFSB in clustered environment on Weblogic?
I definitely agree with the idea of handling the presentation and navigation in the HTTP layer, while handling the session, bussines logic, and transaction issues in the EJB. However, can somebody tell me if it does make sense to handle the JSP navigation logic in the side of the Statefull EJB ? If so, which mechanism should I use to change the tag for the "next page" to retrieve ?
I would appreciate any sugestion !!!
You can separate the navigation logic from the JSP by using a state machine representing your page flow. Use a NavagationJavaBean in the JSP to lookup navigation info from the state machine.
The state machine could store transitions in a database (possibly using EJBs to load page transitions), in a XML file, properties file or harcoded in a Java class.
Don't confuse the idea of navigation logic with the concept of business logic! By the simple definition of an entity bean: They are the objects (entities) of your business. A session bean (Stateful or Stateless): Model the work flow of your business. If you are monitoring transactions it would seem to me that you would want to use an EJB, but for basic navigation why chew up the network bandwith?
The page transition logic is usually static, consesquently the page state machine can be initialized once on system startup. This means that network bandwidth is not an issue in this scenario. The advantage of storing the transition logic externally (database, XML, properties) is to be able to change page flow without changing code, recompiling and deploying the state machine.
On the other hand, I would not advise a database lookup for every page transition per user; this would definitley consume network bandwidth unnecessarily.
I am so glad this conversation came up! Maybe Roger Sessions of objectwatch should be reading this thread.
I am agree with you. In every jsp page lookup to the bean and getting data,it is unnecessarliy increase network traffic. Please send me sample code if u have .
i read one article,in that he told using ejbHanndle object we can reduce the network trafic and we can overcome this lookup in every page.
I think a discussion on this is definitely needed. I feel it is a good idea to stopre session on the server side in terms of stateful Session bean but I still believe as HTTP is a stateless protocol so you can't replace the role of HTTP sessions as even if you save state on the server you still need to save the StatefulBeanHandle on the Http Client session. If the Session data is not very heavy like a employeeId I would prefer to save it on the client Session as I won't have to make a network trip by retreiving the statefulbean from the handle and then get the employeeId stored in the bean.
It makes more sense to keep this ID in the HTTP session.
I would like to know how everybody else feels about it.
A problem with storing the EJB handle in a HTTPSession instance is that if your client opens two browsers (same session) and calls 2 servlets that uses this handle to
remotely call the bean, you may have some exceptions because session beans are not reentrant:
You need to synchronize the remote call within your servlet.
one thing puzzles me when someone mentioned to me that a stateless session bean can replace HttpSession. With a HttpSession, I can set the HttpSession, complete the running of the creating servlet and run another servlet that retrieves it. With a stateless session bean I need to convert it into an EJBHandle which I would need to pass on from servlet to servlet, unless of course I keep it in a HttpSession. So how is it that a stateless session bean can replace HttpSession? It seems to me that they serve different purposes. Can someone explain to me please?
I think that:
- if you use HTTPSession you can use Stateless Session Bean
- if you store an EJB Handle in the HTTPSessiob you must use a Stateful Session Bean.
But for the problems I described before, you have to synchronize. But now, second problem: If you cluster your servlets, what happen? Can you synchonize on objecs stored in HTTPSessions? Or "simply" you have to deal with exceptions (concurrent access)?
I think the issue is less one vs the other, but more about architecting your solution in a transparent manner. Some of this has been touched on in other replies.
Holding state in an HttpSession is a solution. But what if you accessed the system through an alternate channel such as WAP or fat Java client. In these cases you would need to write two more state handling mechanisms, giving you three all together. Add more channels, add more mechanisms!
Therefore I believe the answer is to hold state in the server using Stateful Session Beans making the state handling channel independant. Not only that, it should be possible to use the principal id passed on the EJB call to identify state for a particular client and therefore there should be no need to return a handle to be stored in that client. All business flow can then be handled through Stateless Session Beans which can look up client state via the message principle. Is this clear? I know it's easier said than done and there are issues to do with location of state, failover, home lookup performance etc.
Another question that has arisen is who controls the page flow at the client side if the client doesn't know the state. Mention has been made of a page state machine which seems appropriate. But a *page* state machine is specific to web clients, therefore there needs to be a state machine that can return tags interpretable by any client. I would suggest that the Stateful Session Bean should know its state (prompted by the Stateless Session Beans of course)and that this could be the mechanism for identifying the next page/screen etc. The reasons for this given earlier are still valid.
The sum of all this is that the EJB server manages the business process flow, but also informs the client want to do next. Not specifically, that is for the client to interpret in a channel dependant way. For example, if the next step is 'X', then 'X' could be interpreted specifically by the client as 'Show page X', 'Show panel X', 'Send e-mail text X', 'Send fax text X' and so on.
There are still some outstanding issues to do with synchronisation which are applicable regardless of where state is held. As mentioned, multiple browser windows could be opened potentially giving multiple calls to the same bean - a big no-no. However, EJB doesn't allow us to write *synchronize* methods or code, neither does it allow us to start new threads. But it does guarantee us thread-safety by queuing calls to beans whilst one is running already. I'm not sure, but wouldn't the container see this situation (multiple calls from the same client to different Stateless Session beans to the same Stateful Session bean) as actually different client calls to the Stateful bean - they are on different threads after all and presumably therefore under different transactions.
Sorry this is so long winded but I thought it useful to highlight why I didn't think the issue was just one vs the other.
I do agree with you.
Thank you for the answer.
I checked in the EJB spec, you can read (2.0 spec, still valid for this in 1.1):
EJB 2.0 spec
[6.5.6] Serializing session bean methods
A container serializes calls to each session bean instance.
Most containers will support many instances of a session bean
executing concurrently; however, each instance sees only a
serialized sequence of method calls.
Therefore a session bean does not have to be coded as reentrant.
The container mustt serialize all the container-invoked callbacks
(ejbPassivate, beforeCompletion, ...)
Clients are not allowed to make concurrent calls to a SFSB.
The container must throw a java.rmi.Exception to the second
This restriction does not apply to SLSB.
So, altough this answer is also long, it is definitely possible to use stateful session bean, even in a cluster.
As I read this discussion thread: Different session state storage mechanisms are needed for different purposes. This suggests writing a SessionManger interface and implement the necessary SessionManager subclasses to handle different reguirements. Typical SessionManager implementations could be:
o HttpSessionManger (abstracting the http session)
o DBSessionManager (storing in a database using JDBC)
o EJBSessionManger (using Entity EJBs to store state)
o CacheSessionMangager (using a memory cache, possibly combining in combination with other session managers)
This way, the session storage would be transparent to developers. You still need a clever way to select the appropriate session manager.
I'm new with EJBs. So sorry for my stupid question...
Could someone tell me where can I find an example for calling from servlets session beans.
I want to access session information from a statefull session bean in my servlets. Please help me...:)
Watch into "Mastering Enterprise-JavaBeans" by Ed Roman,the E-commerce example chapter 12-15 (a free download in pdf-format is available from this page)
If you have weblogic, then you can have many examples at <your dir>/weblogic/examples/ejb/basic. (or) just visit, ejbnow.com
I've got a question while reading the Andrew's writing
...it should be possible to use the principal id passed on the EJB call to identify state for a particular client and
therefore there should be no need to return a handle to be stored in that client. ...
What is the 'EJB call'? Is the EJB session bean or entity bean?
Do you mean that an EJB keep states of all users and
return a user state as to the principal id for each call?
Or mean that the EJB keep handles of all statefule session beans for each user?
By EJB call I meant a call from a client to an EJB: either an entity or session bean it doesn't matter. An EJB doesn't keep track of all users but you need to remember (or know!) that for security checking purposes a security context is passed transparently with each call, but only if you have security enabled. The container will use this to make its security checks. The security context will have the user id which it terms Principal (actually this is a CORBA term and this whole mechanism is a CORBA one - probably because the calling protocol is RMI over IIOP). It should be possible to get hold of this Security Context (check the manuals) and thus the Principal (user id). How useful this is depends upon how your users sign-on (whether they share userids such as INTERNET_USER), what security delegation you have defined for beans etc. This user id could be used as a key to a lookup strategy to identify state for a particular user.
Because the user id is automatically and transparently passed around, it could serve as a lookup handle for state management.
Hope this helps.
1. Customer start an order over the web
2. Customer completes order over cell phone
3. Customer calls in to call center to enquire about order
1 and 2 are part of a statefull process. So when the customer starts step 2, the WAP application (or whatever) must determine which state the order is in, the appropriate UI, etc ...
As a developer, I would want all of this state modelled in a database. Using a Statefull session bean would work as well, but the EJB spec doesn't really say how the state is stored.
Also, suppose you want a report of all orders that were started over 30 days ago and then not finished. Statefull session beans don't tell you how they save the state. So how do you query this information?
I would probably want my code (in step 1 or 2 ) to go like:
get orders for $user
display list of pending orders
<users chooses order $order>
get the bean for $order
what is the next step for $order
figure out how to provide a UI to do that step
present it to the user ....
A Statefull session bean would just look at instance data to figure out what the next step is. A Stateless bean would do some sort of database query. The main difference I see is that the stateless bean would need to be passed some sort of order id for each call, whereas the stateless bean wouldn't.
So my point after all of this is that I would suggest the Stateless session bean for a problem like this.
A Stateless session bean would be passed an order_id,
This is regarding the caching of the bean references using the Principal as the key ... for state management ....
I currently use the same mechanism of caching the references of the StatefulBean remotes in an Hashtable with the key as the Princical.getName().
Now my question is .... which it better to hold ... the remote reference of the stateful session bean or the Handle.
What are the pros and cons of either. and when should which one be used.
There seems to be a common understanding that There are primarily two types of clients of EJB based system:
1. Http client
2. Other clients(like Swing based app)
Also we tend to think that whereas Http client reaches business logic through web-tier, other thick clients make direct calls(RMI) to business Logic.
I think in emerging scenarios this is wrong. It makes little sense in making RMI calls from devices like mobile phones, PDA's and other so called non-Http clients. HTTP is most widely used simplest protocol and can be used by most of devices like PDA's and think standalone java clients. The benifits of using HTTP instead or RMI protocol for device-to-server communication are immense. In fact this is one of the major factors in emrgence of webservices which are nothing but RMI services accessed using HTTP protocol.
With this argument that all kinds of clients would invariably use HTTP protocol to access system, we necessaciraly require a web-tier which can understand Http symantic and accrodingly generate business events to trigger business logic in EJB tier. This means that we can build our application logic (flow control, navigation,screens etc) in web-tier and keep buiness logic independent of these things. State machines handling application flow(in terms of screens and navigation) can be implemented on web-tier. This makes sense also since business logic is never to be dependenet on user-system interacation schemes. why should business llogic be concerned about user screen flow!! After all, all these years we wanted to separate application logic from business logic!!
Also the argument that same state machine should be capabale of handling any kind of client or device is weak.
browser based clients can show more information than clients based on small devices like mobile and PDA. And more often than not navigation schemes ,screen flows are to be tailored for different devices and clients. This means different screen flow mechanisms for different types of clients which can easily be implemented on web-tier as web-tier is entry point for all kinds of clients talking to a particular system.
This is with respect to the *page flow control* aspect that has been mentioned a couple of times above.
There seems to be one problem with the fact that the the page flow control should be at the business tier. This defeats the purpose, as i see it, of seperating the business trier from the presentation tier. the task of the business tier should be to ensure that a specific task is completed (it may be in a single or multiple steps or *pages*)... post the execution of this task where the user should be redirected may differs for different users as well as for different delivery channels.
What my understanding is that in the case of one specific task requiring multiple steps or *pages*, the persistence of the state between the sub-tasks that are also requiring a back-end intervention should be done at the business tier ..as this would be fixed irrespective of the user or channel.
however, flow control among tasks .. or for going from one task to another should be a part of the presentation tier. Furthermore, this flow control mechasim can now make use of the HttpSession to store information required between processes.
This implies that you actually end up using both the HttpSession and the Stateful session bean in your applications based on the specific need.
This also helps in providing a proper disconnet between the business tier and the presentation tier, and at a micro level between state management at inter-process and intra-process.
I see that we are trying to solve the same problems, just as when we were working together!
Yes, HTTP is a stateless protocol, but we are all looking at different alternatives to transcending that statelessness. I think there is a continuum, with 'transience' on one end and 'permanence' on the other: HTTP request/response, HTTPSession, stateless SessionBean, stateful SessionBean, EntityBean, database. The issues arise around how much permanence we need.
For example, in our app, the user cannot perform OperationC until he performs OperationB, since OperationB performs calcuations and stores data in the database (via EntityBeans). But where do we store the fact that the user has or has not performed OperationB? The main page has links to OperationB and OperationC, and we need to disable the link to OperationC until OperationB is done. We can put this is the HTTPSession as (part of) a lightweight object. But if the session expires...? We can keep it in a stateful SessionBean (with all the overhead that has been discussed in this thread). We can be REALLY careful and put it in the datbase, with all THAT overhead.
Is this presentation logic or business logic? Well, it's both: we can't know what to display (enabled or disabled link) without looking at the business logic (does table x contain a value in row y for ...).
I agree that we should strive to separate presentation logic from business logic, but often that's like trying to separate the cream from the cofee.
We have a requirement of maintaining client login info/state on the server side. What would be better HttpSession / Stateful Session Bean and why ?
Usually, the HTTP Session, unless it is transactional data, in which case you could use EJBs.
Cameron PurdyTangosol, Inc.Coherence
: Shared Memories for J2EE Clusters
Please excuse any ignorance, I am not upto speed on EJB2, and primarily Weblogic5 experienced.
But, according to Weblogic, and I believe (maybe?) most other app servers, that currently Stateful Session Beans are not clustered. Their home interfaces are, and they do expect to support clustered SFSB at some point, but until then they recommend for fail over/load balancing completeness to continue using the HttpSession.
Excerpt from http://www.weblogic.com/docs51/cluster/overview.html#998260
>When a home creates a stateful bean, it returns a stub that is pinned to the server hosting the home. Because this bean holds state on behalf of the client, all calls must be routed to the single instance. So in the case of a stateful bean, load-balancing and fail-over only occur during calls to the home. Once the stateful bean has been created, all calls for it must go to the same server. If a failure occurs, the client code must catch the remote exception and retry by creating a new instance using the clustered home.
Corrections, questions and comments are welcome.
Sybase's "EA Server" (aka Jaguar)can both cluster and failover stateful session beans.
The EAServer 3.6 version supports J2EE.
Disclaimer: I'm a Sybase employee (but not in the
EAServer group) but I do USE the server for custom
In the world of e-business where the enterprise is trying really hard to have tight intergration of all the channels such as web, wap, call centers, atm, Kisoks etc., through which they conduct business. In such scenerio, it is much better to have channel independent session then channel dependent. HTTP Session object, which is channel dependent, would work well in WEB channel, probabley WAP channel (using standrad gatway which convert WAP protocol to HTTPS protocol) but it will be little bit difficult to integrate call center and other channels which may have alltogether different mechanism to keep track of user's session ( if at all they have such mechanisms!!!!). Hence, it would be meaningful to use EJB stateful session, channel independent, to keep track of session than HTTP session.
As far as scalability issue is concerned, i think it is false claim that stateful programming lowers the overall scalability of a deployment, beacause extra resources r consumed. This argument rests on the fact that stateful components cannot be pooled and re-used becos they hold state from a particular client. The reality is that pooling stateless components has a single benifits : it lowwers the amount of memory being used. No other types of resources r affected, such as database connections or socket connections, as those should be acquired and released just-in-time and should not be part of a components's conversational state. Given that the cost of memory is rarely an issue in a deployment, and that memory prices r at an all time low, the memory consumption of stateful components is relatively unimportant.
I totally agree with you regarding the channel independence of business services and hence the use of Stateful Beans.
I don't totally agree with your arguments regarding scalability however. Stateful beans are inherently less scalable solutions and this isn't just down to memory usage. Scalability also takes into account load-balancing and failover. With Stateless beans, these are a doddle because the app server should direct an EJB call to any available bean on any available server: each call from a client may be serviced by a different bean on a different server. If a server goes down, service is still available. If stateful beans are used, then load-balancing for the initial call is ok, but subsequent calls must always go to the same bean on the same server (obviously). If that server goes down, failover is a function of recovering application state and resource on a new server with minimal disruption to the client (extremely difficult).
Having said all that, I still believe that state should be managed in a channel independent manner and that the failover issue needs to be resolved (by app server providers preferably).
But in the case you use HTTP session, how do you deal with load-balancing and failover? It seems we fall into the same situation with stateful bean.
HttpSession can easily replicated
EdRoman's Mastering EJB2 clearly talks about this :
Stateful Session bean is required to be used when
- If your state needs to part of a transaction ..
- When you have both web based and non-web based clients accessing your system and both need the state
I strongly feel that these two are the best reasons when we should go for a Stateful Session Bean.
Also look at the comparisons given by Peter Zadrozny at the below mentioned link :http://www.sys-con.com/weblogic/articleprint.cfm?id=101
You can't overlook the fact that HTTP is becomimg de-facto delievry channel regardless of kind of devices used. Most of the devices (like PDA,mobiles)are IP addressable and can understand Http protocol.
Webservices and popularity of SOAP proves that in future most of the device to server communication would be carried over Web channel. Benifits of Web as delivery mechanism are tremendous.
Ultimately we might end up with only one delivery channel in sense of transport protocol and that is HTTP.
I have been doing extensive research on this topic because I'm trying to convince fellow architects in my company that SFSB approach is a better approach than HTTP Session(SLSB) approach.
We are a weblogic shop. Prior to weblogic 6.0, SFSB is not well supported in clustered environment. That was the main reason that weblogic users(including my company) used to shun away from using SFSB. However, after weblogic 6.0 was released in late 2000, the problem has been fixed and SFSB works well in weblogic clustered environment since then. I personally tested this feature and found both failover and load balancing works well for SFSB.
There's no doubt in my mind that many companies are using SFSB approach because there are at least four advantages of using SFSB over using HTTP Session and SFSB approach is recommended by J2EE BluePrint as the Best Practice and. However, in order to convince fellow architects in my company, I need to show them the success stories of using SFSB in weblogic clustered environment in PRODUCTION(not in DEV or QA). I will really appreciate it if any of you can provide me these kinds of success stories.
Thanks a lot
What are the four advantages of using SFSB over using HTTP Session?
Session is a term highly linked to HTML client only (and Wap). I don't really see the problem of session with fat fava clients. So I do not really see the advantage of building Statefull Bean to handle Session and why not use a framework using HTTPSession for that.
If you look at Turbine (apache) or Expresso (javacorporate) you can find good,easy framework that will handle "transaction" for a complete problem.
Then you can use Stateless EJB and/or Entity Bean to manage the Business/Storage Logic.
Advantages for Statefull EJB :
- the passivation that can avoid a infinite increase of memory.
- cluster/load balancing
- it is more easy to "kill" one part of the Session that a user can take using ejbremove() than using session.invalidate() (this is for all the Httpsession)
Advantages for HttpSession :
- Easy to setup, test, debug, enhance, ...
- Do you really need a EJB server ?
- Do you prefer taking 3 days to make a ShoppingCart statefull bean or 4 hours to make a session JSP Bean ?
These are my thoughts. I (almost) can not sleep at night when I think on this problem ...
The issue of failover and load-balancing is the same whether state is held in an HttpSession or a Stateful EJB; in fact, once state is removed from the client it becomes an issue. I believe, and I would like someone to confirm or refute this, that a web server persists the HttpSession between browser calls. If so, this is part of a failover solution and would certainly make resolving this problem with HttpSessions easier. However, it comes back to the original point: managing state in this way is channel dependant (to web server channels). What is needed is a channel independant way of managing state so that the problem does not need solving every time the channel changes. This means that state must be held on the channel independent server.
Obviously, it needs to be taken with a pinch of salt. If an application has, and is never expected to have, any other means of access except one channel then the solution should be optimised for that channel.
Here's another thought for you all. If state is managed on the server (stateful session or entity EJB) and business logic is implemented with stateless session EJBs, then each call to the stateless bean will require retrieval of state from somewhere (DB - hence the potential for CMP beans)and a write-back at the end of the method. Deploy that scenario to the internet!
This is why I think failover is difficult, why the choice of HttpSession or Stateful/entity EJB is not clear cut, and why scaleability isn't just about managing internal server resources (memory, disk etc).
It's an interesting discussion folks!
I like to discuss few point about HttpSession here with you friends
For our portal we have a authentication module once the user authenticated only he can access the portal and we are storing the access control for different module with in the session since even if you open as many browser in a single system still it have a single common place and a single cookie shared by all the browser when a new user try to login in through the same PC and if first user is already loged in it overwrite the access control of the first user with the second one.
This technical problem if faced when i am doing my module
This is common problem with any stateless system. Is not it? You will have log the user out before trying to log in using valid authentication cookie. If the client has valid HTTPSession and trying to log in should remove the session and create new session. This is the problem with combing session with authentication and authrization.
Very interresting discussion. From my experience Stateful beans have two major problems.
1. Concurrent access to the same Stateful bean gives an Remote Exception
As one web page can imply many simultaneous request (e.g. for frame content images etc) this is a problem that the spec need to deal with especially as you have the same problem when the same user access a service using different devices. The only way around this as I see is either to synchronize on the bean or catch the exception and retry. Both ways seems messy and the first is forbidden by the spec as well as difficult to implement in a cluster.
2. There exist no inbuilt functionality to lookup a stateful bean. Once a stateful bean has been created one need to store a mapping between a key (sessionId, userId) and the bean handle in order to find the bean at subsequent requests. This mapping becomes a real problem in a clustered environment even if it can be solved using JNDI or a database.
Finally I know that both these issues are beeing addressed by different vendors (Weblogic 6.0 will have an option to allow concurrent access to Stateful beans and I read here that gamestone has a quite sofisticated clustering of sessions) still I belive these problems to be common enough to be handled by the spec.
Anyone agreeing on this? Or have I missunderstood how stateful sessions should be used.
Some comments on your points:
1 - I might have misunderstood what you are getting at here, but the EJB spec does not allow concurrent access to a Stateful bean: all requests are serialised by the container. It is possible for a thread to re-call the same bean but again the EJB spec doesn't allow for this and the container throws an exception. Is this what you are experiencing? Synchronisation should not be necessary on Stateful beans because the container doesn't allow the situation to arise.
2 - You're right, there is no lookup for a stateful bean but I would actually question the validity of wanting to do this on every request from a performance point of view. Looking at the issue at a slightly different angle, when an EJB home is obtained from JNDI then one usually caches it to avoid having to repeatedly look it up. But this only addresses part of your issue, clustering brings in its own problems. Actually this goes to the heart of scaleability in distributed systems: state management (where to hold the state). As we can all see from this thread it isn't a clear cut issue with a right and wrong answer.
Admittedly, having automatic Stateful bean persistence (a la persistent HttpSessions at the webserver) would be useful, but I would be concerned about performance. I think you are right that failover is a common enough problem that it should be addressed by the spec and implemented by vendors. It's the sort of thing that requires the minimum amount of indirection and direct implementation so should logically be performed by the container.
Maybe one day a vendor will REALLY solve the difficult problems for us!
Thank you Andrew for your comments,
To clarify my view on the first issue. I'm well aware that the EJB spec doesn't allow for concurrent access to a Stateful bean in fact it requires the container to throw an exception. This requirment whatever reason it may have really limits the practical usage of Stateful Session beans. If you want a one to one mapping between user and stateful bean, it won't be able to handle multiple request coming in concurrently from the browser. For example if you want to use the state in the stateful bean to redirect image requests.
To solve this one must let the servlet serialize the request this becomes virtually impossible if the servlets handling incoming request are executing on different machines. Why can't the spec at least require the Container to wait for the bean to become available instead of throwing an exception???
Concerning the second issue:
The reason I would like a lookup mechansim is the following. Imagine that you have two separate webservers that each handles two sequential requests from the same user. At the first request a stateful bean is created and the handle stored locally in the HttpSession fine.
The second request coming in to the second webserver can't access the HttpSession residing on the first machines JVM so it can't get a hold of the handle. That's why I would like to have a lookup mechanism, once the lookup have been done one can store the handle locally in order to process future request.
I sort of see what you're getting at. A multi-threaded client cannot share the same session bean instance because concurrent access is not permitted. I guess the only way around this is to synchronise and serialise at the client. In your specific example, of multiple concurrent requests from the browser, this is indeed difficult because the incoming Http requests could get sprayed to different webservers in a load-balancing scenario. But I have a question about this, and forgive me but my knowledge of how browsers work is not great:
1- Do browsers really make concurrent requests? My understanding is that only one request is sent at a time.
2 - If it can make multiple requests, wouldn't you normally build the page on the webserver first (say with a JSP) before presenting it to the browser, in which case the build logic is running under one thread of control. This shouldn't cause concurrency issues.
I guess thats by-the-by in any case. Your requirement is for multi-threaded clients and this doesn't fit in with the EJB world. Perhaps the ability to concurrently access beans will be written in to the spec if enough vendors build that functionality into their servers. In the meantime you are right, it is a problem for you!
These sort of problems are quite interesting to solve and of benefit to others. Why not start a new thread off with a bit more background information and we can have a bash at coming up with some neat architectural solutions there. I'm just a little aware that it is going off subject with this particular thread.
Actually, there is a case I can think in which the browser sent out concurrent request to the server: multiple frames.
And I met this problem in my project. And there's no way to serialize those request (You hve no control on the servlet threads which are serving the requests.) I ends up replace the stateful session bean with a SLSB and keep the status of client in the servlet layer. I know it's not a common case but it's there and very annoying. Any idea about the solution to this scenario?
perhaps you should ask the question in a new thread because it is going off topic. You don't say what the browser is requesting in each of the frames - is this important to know? The thing is, with J2EE isn't the idea to build the page *before* sending it to the browser? If you did this would the frames have a need to go to the server to do their thing - surely that requirement would have been fulfilled as the servlet was building the HTML for the page? I just don't know enough about what browsers do and don't do right now, my expertise lies in middle-tier and integration architecture design. If building the page first doesn't solve the problem, then I see no other way of doing it with the current EJB spec than keeping the required data in the servlet layer. Alternatively you could embed it is as hidden fields in the HTML which would help you if your HTTP requests are load balanced.
I really think this would be better discussed as a seperate thread because it is an interesting problem. I bet you and Dave are not the only ones to have experienced it!
No matter what your page looks like, the browser can always cause multiple concurrent requests to execute because the user can stop and refresh the page mid-query. If your method takes more than a second to execute (say your database/server farm/random bottleneck was heavily loaded), this is a very likely scenario.
Nasty problem. Since synchronization is not allowed on the bean and not guaranteed by the container, it seems like we have no choice but to handle the exception for every single method call in a web environment. Or let the user see an error message. Or not use stateful sessions...
This really sucks.
The problem of concurrent requests from client is an almost unavoidable problem, no matter how you implement your page. This is because not only the html content causes concurrent requests (frames/dynamic animations) but also due to user interaction. Therefore it is better to user httpsession to avoid exceptions. I only recommend using SFSB when a transaction is suspended due to a very small amount of data that needs to be changed/confirmed.
Eg. A user signs up for an email account. He/she fills in the whole form, but the username he/she chooses already exists. In a case like this instead of throwing the whole form + data at the user, it will efficent to only re-fetch the username from the user and keep the rest of the data in a SFSB. The advantage increases if the user has to make multiple attempts to get a unique username.
We can solve this problem by synchronizing at the controller level, say the servlet, which controls all calls to all beans, right? Or am i missing something?
Concurrency can be addressed by making calls to EJB thread safe. For example, You can have RetrieveThread that implements Runnable and the constructor can take in a session bean. For your call to the sessionbean, you must create a new Thread object passing this Runnable RetrieveThread and start it in a Try-catch block. The run method would encapsulate the actual call to the session bean with a mechanisim to check if the request has been cancelled ( like the user pressing the stop button or refresh in the middle ). If the user pressed any of these buttons you can always interrupt this thread and set some flag which can be used to detect if the request has been cancelled
Yes, concurrency can be synchronized at the controller level, but yuck, what a mess. Probably the easiest way would be to create a decorator object which implements the BusinessInterface of the session bean, and then always save the wrapped version in the HttpSession (or wherever).
Still, if the user hits "reload" a half-dozen times, he/she will have to wait for *all* of the method calls to finish executing in serial. Since the most likely case of this happening is long-running queries, it could get painful... unless the results are cached in the session bean for a short period of time, which would solve the problem but adds complexity. Hmmm.
I just ran some tests against my server (Orion) and discovered that, contrary to the spec (but more desirable, IMHO), it serializes method calls on stateful session beans.
A little birdie at BEA :-) informs me that they have a special patch available for demanding customers which serializes method calls to stateful beans.
Anyone know what the other servers do?
I agree, if you store a Remote reference in the HttpSession, it will not work in the load balancing environment where Request-1 from User-1 is redirected to WebServer-1 and Request-2 from same user is redirected to the WebServer-2.
If container allowed lookup on a Stateful SessionBean, it would make things much more easier because then a StateFul SessionBean id for that specific user can be passed on to the browser as a cookie, and later, using this cookie value, appropriate stateful sessionbean object can be looked up.
<strong>Well, until lookup functionality is available, how about using a SessionManager functionality?</strong> What I mean is .... Create a SessionManager object and put it in a JNDI tree. This session manager is responsible for creating new UserSession objects and/or allocating a UserSession object for the given sessionid. SessionManager is also responsible for managing number of in-memory sessions to a predefined limit as well as writing them to persistent storage if necessary. It also checks and removes any expired sessions from the memory and/or persistent storage.
The UserSession object itself can implement either a Remote or a Serializable interface as appropriate.
<strong>Any thoughts or experiences on using a SessionManager sort of functionality in an EJB application? </strong> I am not saying that it would be beneficial, but jjust interested in learning about what the experts think! One way, the stateful session bean management is very similar to the SessionManager concept I discussed above, except that it does not allow lookups, and also a Stateful SessionBean object may be accessible only on the EJB Server instance where it was created (except in some app servers where it creates a backup copy on one more instance and contineously synchronizes it between these two server instances). May be, by EJB 3.0, these issues also will be addressed by the spec.