I was checking EJB stateful beans, the typical example for using this bean is in a shopping cart.
So in the example what is done is check in HttpSession if the EJB exists, if not, one EJB instance is called and then upload to session using the HttpSessionId as identifier.
So, what is the advantage of using a stateful EJB when I could use a simple POJO to do exactly the same?
I guess the typical answer is that even if the HttpSession goes down the EJB still lives in the server container. If this is true, how can I recover that EJB from the EJB pool? given I don't have the HttpSessionID anymore.
Is there another approach to recover EJB's that are living in a container?
The shopping cart of a Stateful EJB hosted within an http session is in my opinion the typical example of something that shouldn't be done for a very simple reason: a shop online purpose is to increase traffic and number of (paying) users. A Stateful bean on the opposite is not recommended with this kind of web site, it doesn't scale.
Stateful Bean are something that should belong to the realm of desktop applications i.e. Swing, JavaFX etc... it has little to do with an www shop online.
Of course keeping things in a session is much lighter than having a Stateful bean holding data.
I cannot think of any trick to recover a Stateful EJB once you loose its reference.
Also, what do you mean with "if the session goes down" ? If you mean because of a server crash, keep in mind that if the EJB resides in the same server then an EJB (Stateless, Stateful, Singleton, etc...) cannot survive a server crash.
Related
Need to call a EJB service from the servlet context listener's contextInitialized() method. Application is running on JBOSS, though the context listener works fine, I'm not able to access the EJB bean through JNDI look up.
Because the web deployment in JBOSS happens before EJB beans are bound with JNDI tree. How to overcome from this? Is there a way to configure JNDI bind early or start the web deployment later once EJB's are completely deployed?
I had put Thread.sleep() before the service call in the contextInitialized() method, it is working fine in my JBoss5.1.0 GA, and the same did not work in other machines JBoss of same version.
Applications needs this because, we want to load some master data from the DB and make it available in the web layer (kind of caching). Does JBOSS startupmbean suit this requirement? If yes how can I make the data available to web layer?
Also if any alternative ways are available, please suggest.
Poll for the EJBs in contextInitialized(). So instead of just sleeping for a certain time, try to connect to the EJB. If that fails, sleep, and retry, until the EJBs are available. In this case the context initialization is blocked.
Implement the cache as a lazy one: Fill the cache during the first query (and use the same polling procedure: connect to the EJB, retry until it becomes available). In this case the cache blocks.
You could split your deployment into two parts: One for the EJBs, one for the web application. Then deploy the first, and delay deployment of the web application until the EJBs are bound (either by watching the log file or by trying bind to the EJB from a command line app)
I wanted to understand better how and when it makes sense to use the prototype scope in Spring. Seems that it is similar how the stateless session beans have been handled in the EJB world (although, the EJB container would release an instance from a pool of stateless session beans that would be created rather than creating a new instance on demand).
I have a few basic questions about that:
1) From an architecture standpoint, when does it make sense to use prototype-scoped beans in a typical J2EE web application (Spring MVC/Hibernate or JDBC template DB access)?
2) Is there a concept of creating a pool of such prototype instances similar to the pooling that the EJB server would do with the stateless session beans?
3) Should the service facade (that is similar to the Session Facade in EJB) be created with a prototype scope and would that help in dealing with the concurrent requests coming from a web tier? And how do I control the number of instances that are created (limit to certain manageable number and, preferably, pool them)?
you would want singletons for services, assuming your services are stateless. That way you only have one instance of each service, and since they are stateless they are threadsafe.
you would want prototypes for things like request actions (e.g. in struts), so a new object gets created to handle each request. Those prototypes can be wired up to singleton services.
from the documentation:
The non-singleton, prototype scope of bean deployment results in the
creation of a new bean instance every time a request for that specific
bean is made. That is, the bean is injected into another bean or you
request it through a getBean() method call on the container. As a
rule, use the prototype scope for all stateful beans and the singleton
scope for stateless beans.
If you define your service in singleton scope in your spring config, what would happen if more than one user try to access it (ie as dependency injected into your controller) at the same time? Should it cause any conflict? Or the IoC container will hold the later call until the first one finish? If so it should slow down the performance in large applications, which sounds not right to me. Could any one give me a correct answer?
BTW, as I can remember, if it is not a singleton one, IoC container will pool few instances based on the number of requests. Could some one confirm it?
what would happen if more than one user try to access it (ie as dependency injected into your controller) at the same time?
A singleton bean can be accessed many times concurrently. That's why it always has to be thread-safe
Should it cause any conflict?
Only if you fail to make it thread-safe
Or the IoC container will hold the later call until the first one finish?
No, that would be awful
BTW, as I can remember, if it is not a singleton one, IoC container will pool few instances based on the number of requests. Could some one confirm it?
Spring has the following scopes (see Bean Scopes reference):
singleton (only one instance is managed per application)
prototype (a new instance for every injection)
session (one instance per HTTP session, only in Spring MVC)
request (one instance per HTTP request, only in Spring MVC)
global session (one instance per global HTTP session, only in portlet-based Spring MVC)
Also:
As of Spring 3.0, a thread scope is available, but is not registered by default. For more information, see the documentation for SimpleThreadScope.
What you describe is an Object Pool. In Spring that would be implemented as a Prototype-scoped FactoryBean. And internally it would use a library like Apache Commons / Pool.
Singletons are just that - singletons. One instance is managed by the Spring context, and all requests go through that one instance concurrently. It's up to you to make that thread-safe.
If your bean isn't thread-safe, then consider using non-singleton-scoped beans. Spring lets you use request, session and prototype scopes.
I have gone through various books on stateful and stateless session bean and how they work. I want to know the real usage of these ejbs and advantages over using plain java classes. Basically when do you go for stateless ejbs and when do you go for stateful ejbs. I want a real time application.
the usage of these type of ejbs are usually in service layer as service classes.
EJB3 stateless and stateful bean are actually POJO (with some annotations) and they don't have any big difference with normal classes.
but in term of usage, they have some abilities that you can't find in normal classes like:
they can be called remotely (e.g. RMI protocol).
they can use application server context resources like DB Connection and Transactions.
stateless or stateful:
- if a task or process can be done in a single step (by a single method call) stateless is the right option
like a authentication process
- if a task needs a series of method calls (more than one) and you need to keep previous results to use them in next call, then go for stateful.
like a shipping process (select items, add/remove and then do the transaction)
http session or stateful?
ejbs can be served in application server and they may have different type of clients like a normal swing application or ..., so you can't relay on http session in these cases.
if your appserver and webserver are different (distributed) its not good idea keep data in http session and pass/getback it to/from app server (network overhead).
Stateless session bean are lightweight: they do not store information about a specific user. They are usually used in a static way. For example a client ask for a product information will communicate with a stateless session bean. ("You want the price of product 'YXZ', here you go!")
Stateful session bean however remember's the client information. They contains data about the user actions. For example, let's say a user go through a shopping cart. The steps will be stored in a stateful session bean (for example, user it at the payment step).
You really need both type of session bean in any website. Unless you web site is so basic that anything can be done with stateless session bean (a read-only web site really).
Any web site that track a user through cookies, will need a stateful session bean. Be aware however that you can decide to put very little session information in a session bean and store that information in a database. But you still need some session management.
Developers prefer to maintain state in web layer in modern enterprise applications. I have never seen a real world web application using Stateful Session Bean. It is a scalability issue also.
An example is a shopping cart stateful session bean that tracks a client's product choices and can execute a sale when requested.
How is that instance pooling with EJBs can improve performance? Wouldn't you be able to accomplish the same performance just with threads like a java servlet?
Or perhaps instance pooling with EJBs happens for another reason?
Instance pooling not only helps because you can re-use objects (and avoid costly object creation), but also allows the app. server to manage the load correctly. It's app. server specific, but you can normally specify max-pool-size, min-pool-size, pool-resize and the timeout.
When the pool has reached its max-pool-size capacity, requests are served using the existing instances, and will time out if no instance is available within the expected time frame. That may degrade the quality of service of the application, but at least it doesn't blow the app. server itself. That's the same as with a web server.
A few notes about thread-safety:
Sect. 4.3.13 "Serializing Session Bean Methods"
The 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.
As per the EJB spec, all requests to a specific instance of a bean are synchronized by the app. server. This is, for instance, to allow a stateless session bean (SLSB) to store a database connection in one of its fields. The fields of an SLSB should be transient, though. (The bean instance can be destroyed/re-created any time.) With the synchronization, the app. server ensures the SLSB is thread-safe. Without the synchronization by the app. server, the developer should ensure that the SLSB is thread-safe, that is, it should have no fields.
Note: It's rare to have fields in an SLSB. Most SLSB are thread-safe by nature. I would not recommend storing the connection in field for instance. Better obtain one in the method, and release it in the method asap.
I think instance pooling is used when the beans are expensive to construct. By letting the next request reuse the same bean you don't have to construct another instance.
If the bean itself is cheap to construct and the cost is in the work that it's doing, then instance pooling isn't worth the hassle.
I think the advantages would be similar to those of connection pooling. Having instances ready in a pool avoids the overhead of creating a new instance every time the EJB is requested.
Another advantage, depending on how you look at it, is that by using a maximum pool size you can limit the damage a runaway application can do by forcing it to wait for an instance to become available. This can help prevent poorly written apps from monopolizing server resources.
AFAIK the fundamental reason is the different threading model compared to the servlet's one. In case of servlet, there is only one instance and many threads can operate on this intstance at the same time. It is the developers responsibility to ensure proper synchronisation.
In contrast to this, ejb container allows only one thread at the same time to operate on the bean instance (including necessary synchronisation at the background). Thanks to this, developer does not have to care about synchronisation, and what's more using synchronisation in the bean's code is forbidden by the spec (in fact you can do it, but you have to consider the performance consequences).
So to enable concurrent processing, you need to pool multiple bean instances so that multiple threads can access them simultaneously. The size of the pool can be tuned depending on what kind of work is done inside the bean. The basic rule is:if the task is I/O bound, you need big pool so that the cpu time is not wasted when waiting for i/o response. If the task is cpu bound, the pool should be as big as much processors/cores the machine does have. But the tuning should be based on measuring.
One more note on the servlets: you can enforce the same behaviour as ejb when using SingleThreadModel interface. But in fact this is not much used I guess.