As per my understanding stateless session beans are used to code the business logic. They can not store data in their instance variables because their instance is shared by multiple requests. So they seem to be more like Singleton classes. However the difference is contain creates (or reuses from pool) the separate instance of stateless session beans for every request.
After googling I could find the reasoning that the Java EE specification says they are suppose to be single threaded. But I can't get the reason why the are specified to be SINGLE THREADED?
The SLSBs are single threaded because of the TX Context, Principal is associated with a bean instance when it is called. These beans are pooled and unless the max pool size is reached are processed in separate threads ( Vendor dependent).
If SLSBs were designed thread safe every call would have looked like a servlet doGet/Post with request info containing Tx Context , Security Context info and etc. So at least the code looks clean (developer dependent).
The primary reason stateless session beans are single threaded is to make them highly scalable for the container. The container can make a lot of simplifying assumptions about the runtime environment. A second reason is to make life easier for the developer because the developer doesn't have to worry about any synchronization or re-entrancy in his business logic because the bean will never be called in another thread context.
I remember the reasoning being discussed in the reviews of the original EJB 1.0 specification. I would look at the goals section of the specification. See http://java.sun.com/products/ejb/docs.html for the list of specifications.
Related
I have a war file deployed in glassfish. We have some stateless session beans and we have 1 synchronized method in it.
However, I am noticing that more than 1 thread is able to enter the synchronized method concurrently. Is it possible that glassfish is instantiating 2 instances of this bean class? Is there any way around this?
Yes, of course it's possible. The spec even mandates that concurrent calls are handled by different instances.: this is one of the services offered by the container: it makes sure that concurrent calls are handled concurrently, and not sequentially, and you're free to implement your sesssion bean without caring about thread-safety (for example, by using instance variables), because the container takes care of it.
What you want is a singleton.
I have this new mvc project where all beans are default scoped(no prototype or session).
with single application context.
i want to know
by making all beans to be default scoped are we trying to achieve the whole application to be run in single thread?
if so will that make each httprequest(from multiple or same sessions) to be queued until the previous one completes?How to avoid such scenario any advice or link would be helpful.
I am relatively new to spring and java development.
Because Spring beans are typically stateless, you can safely call them from multiple threads. That's how your application works: there is only one instance of every controller, service, DAO, etc. But your servlet container (through Spring) calls these beans from multiple threads - and it's completely thread safe.
In fact in plain servlets the situation is the same - there is only instance of each servlet and it can be accessed by infinite number of threads. As long as this servlet is stateless or properly synchronized.
Do not confuse Spring with stateless session beans in ejb that are pooled and each client gets its own instance from the pool.1
1 - In fact that's a bit dumb - since the beans are stateless by the definition, there is no point in pooling them and preventing concurrent access...
Singleton means that the there will be only one instance of each bean. Generally, such beans are processing elements that carry no state. The methods called on them are passed the context which contains the inputs to work on. Hence the method calls on such singleton beans are inherently thread-safe.
In a code base that I've inherited, there's an MDB which is calling SingletonBeanFactoryLocator().getIntance().useBean() to get a factory reference in its ejbCreate(), and then getting a specific bean from this factory and storing it as an MDB instance variable. (The factory is of type 'ClassPathXmlApplicationContext').
The confusing part is: after that bean is obtained, it's calling 'release()' on this factory reference in that same ejbCreate().
Now, this MDB is pooled with poolsize 'x' and what I've observed is, beans defined in the context xml are getting created 'x' number of times. So my guess is, every time the 'ejbCreate()' executes, it's creating a context and its beans afresh.
I checked Spring doc for 'release() above which says:
In an EJB usage scenario this would normally be called from `ejbRemove()` and `ejbPassivate()`.
So here're my questions:
1) is it really creating a new context and new beans everytime ejbCreate() is called?
2) if yes, what happens to the context/beans created in the previous call (e.g. if the beans are singleton themselves, will they be destroyed)?
3) is this the right way to use SingletonBeanFactoryLocator (possibly for thread safety issues) in the context above?
4) if not, what is the right way to use it?
EDIT: one possibility I can think of is to make the concerned beans prototype to make each MDB instance thread-safe, so there's no need to release and recreate the context. Awaiting other comments/suggestions.
Yes
Nothing happens. The same objects will still be in the same MDBs. The MDB doesn't care and Spring is out of the picture at this point.
That really depends on the use circumstances. If you just use Spring to assemble objects and every MDBs should have it's own instances then the answer is yes.
Depending on the use case SpringBeanAutowiringInterceptor may or may not be a better alternative.
Prototype can be tricky. You have to understand your beans and the consequences well to make it do what you expect. That's why it's generally best to make spring beans stateless.
Update:
There is actually a race condition. If the container decides to run the ejbCreate() of two MDBs in parallel then they both will end up sharing the same application context.
Update 2:
I could not find a section that explicitly allows EJB creating through parallel threads but I could also not find a section that explicitly forbids it.
Given the following sections from the spec I assume it would be in the spirit of the spec to do it.
2.4.2 Message-Driven Objects
A typical EJB container provides a scalable runtime environment to execute a large number of mes- sage-driven objects concurrently.
5.2 Goals
A further goal of the message-driven bean model is to allow for the concurrent processing of a stream of messages by means of container-provided pooling of message-driven bean instances.
5.4 Protocol Between a Message-Driven Bean Instance and its Container
It is the container’s responsibility to ensure that the message-driven bean comes into existence when the container is started up and that instances of the bean are ready to receive an asynchronous message delivery before the delivery of messages is started.
5.4.11 Concurrency of Message Processing
A container allows many instances of a message-driven bean class to be executing concurrently, thus allowing for the concurrent processing of a stream of messages. No guarantees are made as to the exact order in which messages are delivered to the instances of the message-driven bean class, although the container should attempt to deliver messages in order when it does not impair the concurrency of mes- sage processing.
What is the reason why the Application Servers pool the Stateless EJBs?
I can understand that it is usefull to control the workload of the application for incomming invokations, but this only justifies the pooling of the EJBs that server as FAÇADE with the invoker client.
Does it have any benefit to pool the internal EJBs (those that are not exposed and only invoked internally to perform business logic)?? instead of use a shared single instance (like Spring does).
I can think about at least one downside: a highly used internal EJB could act as a bottleneck.
Stateless session bean EJBs are not necessarily thread-safe. They can be holding resources like JMS sessions which cannot be shared with more than one thread at a time so the server will pool them so that it can serve multiple requests for the same bean concurrently (JMS resources are also pooled, but I'm just using that for the sake of example).
I would also like to know why stateless EJBs are pooled. But i want to know why they're pooled rather than being created and destroyed on demand. The fact that instances can be reused for unrelated requests significantly complicates the implementation of stateless beans (it means you have to be incredibly careful about the use of instance fields), and i don't see any significant benefit to it.
Specifically, i don't see any performance benefit to it. I poked through the implementation of stateless beans in JBoss (6, IIRC), and its only the bean instance itself that's pooled; the plumbing to handle method invocation is recreated from scratch each time it's used. That means that the only performance saving is a single object creation, which should be a trivial amount of time. The only situation in which i can see it being non-trivial is if the bean acquires heavyweight resources, and holds on to them between invocations. However, in that case, the bean is really being used as a glorified, badly-managed, pool; the correct solution would be to pool the resource directly!
Now, EJB has been around a long time. Back when they first came out, object creation was expensive, so it made sense to pool them. But those days are long gone. Why was pooling not dropped in EJB3?
In a traditional n tier web app with servlets for web layer and ejbs(2.0) for biz layer, what is the rationale behind making the servlet model multi threaded and the ejb model single threaded?
i.e there is only 1 servlet instance for all requests, but for ejbs, for each request, there is a new bean instance assigned from the bean pool.
There is indeed only one instance for a specific Servlet since they are supposed to be stateless. In practice this isn't always the case, but so be it.
There are however multiple instances of Stateless session beans (SLSB), and those are pooled.
By their very definition, stateless session beans are stateless, so on the surface this seems like a paradox. The things is that while stateless session beans are stateless with respect to individual calls being made to them, they in fact very often have state.
This state is in the form of references to other resources. The JPA entity manager, which is not thread-safe, is a prime example here. During a single call to a stateless session bean, the caller must have exclusive access to this resource. When the call returns, the next caller can have exclusive access, etc.
If a single instance was used, then either all callers would have to wait on each other (which is of course killing for performance), or they would have the access this single instance concurrently. In the latter case, the bean implementor has to do manual locking of the non thread-safe resources like the entity manager which is often brittle, error-prone and in the end still causes callers to wait on each other.
So, in order to improve performance and still have the safety guarantee, multiple instances are being used.
Those instances are then being pooled and re-used instead of created fresh for each request, because finding, initializing and injecting all required dependencies of the bean can potentially be time consuming.
All of this thus automatically also means that if you inject an entity manager or other non thread-safe resource into a Servlet (which is allowed), you may run into problems. This is a small loop-hole in the Java EE architecture, which is of course easily worked around by simply making use of stateless session beans.
I think that typically servlets present thin facade to the heavy logic implemented in EJBs. Servlets should be stateless and therefore there is no reason to create more than one instance of the same servlet.
If you are using stateless beans only I think that there is no reason to have more than one instance too. But statefull EJBs have state and therefore you need instance per simultaneous request.
I hope I did not say bullshit.