With EJB (3.x) you have a choice of Session Beans: #Stateful and #Stateless. If I understand the basics behind these two options:
#Stateful - Each user/client gets their own and is thus typically not pooled; maintains state across multiple requests
#Stateless - Does not maintain state between requests and thus is usually pooled so each new client request gets a fresh bean
My core question here is quite simply, however there are several mini-questions that I have that are tangential to it: how does my POJO design differ between #Stateful beans vs. #Stateless? In other words, if I have a HelloWorld bean that implements the Hello interface, how does that POJO's design change depending on whether I want it to be stateful or not?
Tangential to this:
What different restrictions does the app container (in my case GlassFish) impose upon the EJB depending on whether it is stateful or not?
In the case of #Stateful, how does a client-side request from the same user/client get mapped to the correct bean (the one maintaining the client's state from a previous request)?
When do session beans die? I assume its immediately after the request is done for #Stateless, but no clue for #Stateful.
Thanks in advance for any clarity here.
Regarding the core question "how does my POJO design differ between #Stateful beans vs. #Stateless":
Your hello world example is an excellent example of a #Stateless session bean: the implementation has no state (no class instance variables). It makes no assumptions about state. If you do need "more information" in a #Stateless bean look it up, (re)compute it, etc. If you break this rule and define instance variables on the bean, you have no assurance that the information will be what you expect it to be on each invocation of the bean: don't do it.
Your design of a #Stateful bean would keep internal state (class instance variables) that the container will preserve for the life of the bean; the bean must be Serializable. There are very real run-times costs (memory, and managing the issues around your second tangential question, particularly in a clustered environment) associated with keeping the bean around for the life of the session - so use this only as appropriate (which justifies the existence of #Stateless beans).
For example, consider a simple sign-up page: enter user name, email address, etc, followed by "are you sure"? A #Stateful bean can preserve this temp information until you're ready to submit it to a back end.
Google for examples; here's one: http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Application_Platform/6/html/Beta_Documentation/Stateful_Session_Bean_Example.html
HOW the client-side gets mapped to the correct #Stateful bean is truly implementation dependent (not spec'd), however you can expect that it's managed analogous to how your Servlet Session information is maintained. That said, don't confuse the Servlet Session with a #Stateful session - they're not the same thing at all.
For Java EE 5/6 in your #Stateful bean annotate one method with #Remove, and when your client calls that method it'll be released back to the ether. Outside of that, as long as you hold a reference to the #Stateful bean (i.e. in your Servlet Session) you can expect that #Stateful bean to be around when you need it.
See also: http://docs.oracle.com/javaee/5/tutorial/doc/bnbmt.html
1) Your EJB/Pojo really doesn't know the difference. You as a developer do, but at the code level, a Stateless bean looks pretty much like a Stateful bean. The life cycles and callbacks are effectively the same, the distinction is that the client has more control over that lifecycle, whereas with a Stateless bean the container has control over that lifecycle.
2) Your client simply maintains a copy of the Session Bean instance. So, for example, in a web container you can simply stuff the instance in to the session. What you don't want to do is simply continually inject a Stateful Session bean (using #EJB) for every request as this will create a new one each time. It's better to check your session, if it does not exists, then look it up normally.
3) Stateful beans can have a method annotated with #Remove. When you call this method, the bean is destroyed. If you do not call this method, the container has a timeout facility that will reap the session beans automatically after some configured duration. There is no expectation of a Stateful bean surviving a server restart (though that contract may well be different in a clustered environment).
There's also a bunch of legacy EJB 2 behavior that mostly works, you just have to jump through hoops to get to it, the modern stuff is easier.
If you have instance variables in a Stateless Session Bean, their values will be meaningless (practically speaking). This is because you never know which instance of a Stateless Session Bean will be retrieved from the instance pool to service a request.
Stateless Session Beans only die when the container decides to kill them. They are instantiated as needed, and will only be destroyed if the container decides to destroy them (for example if it decides to make the instance pool smaller). You say that you assume they are destroyed after the request, but this is incorrect. After the request they are returned to the instance pool and remain ready to service the next request.
Because questions are wide, I will try to answer shortly and provide links to additional information.
What different restrictions does the app container (in my case GlassFish) impose upon the EJB depending on whether it is stateful or not?
Main difference in your case is told with following quotation from specification:
Stateless session beans are session beans whose instances have no
conversational state. This means that all bean instances are
equivalent when they are not involved in servicing a client-invoked
method. The term “stateless” signifies that an instance has no state
for a specific client. However, the instance variables of the instance
can contain the state across client-invoked method calls. Examples of
such state include an open database connection and an object reference
to an enterprise bean object.
In the case of #Stateful, how does a client-side request from the same user/client get mapped to the correct bean (the one maintaining the client's state from a previous request)?
In client side you have to store reference to business interface of stateful session bean. This object you got from the EJB container. It is container created object that contains details about how to locate server side object. Some information about these proxies in GlassFish can be found from:
When do session beans die? I assume its immediately after the request is done for #Stateless, but no clue for #Stateful.
No, stateless session bean (SLSB) do not die after request. Life of stateless session bean is:
It is created when container decides so. This happens naturally in
some point before it is used, but otherwise it is in the hands of
container. After SLSB is created, it is placed to pool.
When some client needs to call method in SLSB, one instance is taken away from pool for duration of method call. After method call is finished, instance
is returned to pool. Then this instance (amoung others) is ready to serve next client.
Life of SLSB ends when container decides to adjust size of the pool
Life of stateful session bean (SFSB) is roughly follows:
New instance is created by container when JNDI lookup or injection happens.
During its life time SFSB can server multiple method calls. It can also be passivated (basically stored to disc to save resources) and activated again.
Life of SFSB ends when remove method is called or timeout (SFSB was not in use for some duration of time) happens. Containers usually have implementation specific default timeout and timeout can be also adjusted. In Java EE 6 (EJB 3.1) this timeout can be adjusted per bean basis via StatefulTimeout.
Additionally instance of session bean is discarded when system exception occurs. System exception is RuntimeException (that is not marked as application exception) or java.rmi.RemoteException. Fact that instance of SLSB is discarded is transparent to client. Next call will be for sure served by other instance
of SLSB. In the case of SFSB all possible future business method calls will fail, because server side instance of SFSB does not exist anymore. Details can be found from EJB 3.1 specification chapter 14.
Definitive and detailed description of life cycle can be found from EJB 3.1 specification (4.6, 4.7). Description more detailed than above and with graphs is available in Java EE 6 Tutorial.
And what is the main effect to the design of Hello service:
#Stateless
public class HelloStateless implements HelloRemote {
#Override
public String getGreeting(String name) {
return "Hi " + name;
}
}
/**
* This design is not possible for Stateless, because
* subsequent calls to setName and getGreeting can be
* handled by two different instances. For stateful it
* is fine, because we use one exclusively one instance.
*/
#Stateful
public class HelloStateful {
private String name;
public void setName(String name) {
this.name = name;
}
public String getGreeting() {
return "Hi " + name;
}
}
Related
I have created a stateless session bean(SLSB) and doing a local call from the same JVM. I have a BO local variable in the SLSB when initializing i am setting this value and in the next call i am performing some business function but in the next call i am unable to get the value which i have set in prev. call.
which seems to be according to the SLSB functionality but there is a similar fucntionality which is working in another part of our application. I have confirmed both are SLSB and no connection pooling is done in the ejb-jar.xml and weblogic-ejb-jar.xml(also both are same) also i have debugged both the class but no clue how it is working in the other class.
I am wondering is there any other way in which we can do the state full behaviour of stateless session bean apart from connection pooling.
The important (if slightly obvious) lesson here is: Don't store state in stateless session beans. If you want to store conversational state, use a stateful bean, if you want shared state use a singleton bean. You could also use an entity bean to persist the state.
The reason this is working elsewhere is most likely to do with bean pooling. EJB containers mostly use bean pools to store their stateless beans, as this gives the best performance and scalability. When a request comes in, the container chooses a bean from the pool to service it, takes it out of the pool, the bean handles the request, then is placed back in the pool. Which bean gets chosen is up to the container, since in theory they are all interchangeable.
If you're setting a member variable in your bean then finding (some of the time) later calls find the variable set to your value, this shows that the container has given you the same bean instance back. This is non-deteministic - it depends on server load, pool size and the container's strategy.
I know that:
For stateless session beans the server can maintain a variable amount
of instances in a pool.
Each time a client requests such a stateless bean (e.g. through a
method) a random instance is chosen to serve that request.
My question is: Why a pool is needed?
Shouldn't one instance of a EJB stateless bean be enough to serve all requests ?
Also if the server for a given stateless bean is using a pool of 10 instances,
is 10 the maximum number of requests it can handle on such a bean ?
Can you help me clear my doubt?
EDIT:
section 4.3.14 of the ejb 3.1 spec gives the answer.
4.3.14 Serializing Session Bean Methods The following requirements apply to Stateless and Stateful session beans. See Section 4.8.5 for
Singleton session bean concurrency requirements.
The container serializes calls to each stateful and stateless 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 stateful or
stateless session bean does not have to be coded as reentrant.
The container must serialize all the container-invoked callbacks (that
is, the business method interceptor methods, lifecycle callback
interceptor methods, timeout callback methods, beforeCompletion, and
so on), and it must serialize these callbacks with the client-invoked
business method calls.
Searching a bit online, my quess is that a thread pool is necessary
to the specification that imposes that EJB stateless methods
are thread safe.
So if we have,say 10 beans in the pool, only 10 requests can be served simultaneously, the other will be queued and assigned to the first free bean.
Please correct me if I'm wrong.
If you create a stateless session bean, It does not care about which client is calling, It allow you reuse the instances across multiple clients, with this you are going to have a better performance in your application, It is one of the principal differences between a stateless session bean and a stateful session bean.
A stateful session bean is going to create one instance per client and it is going to reduce the performance of the application because you are going to have many instances at the same time.
To have a pool allow you to increase the number of stateless ejb instancess depending of the load of your application :)
Edit
If you want only one instance to all the request and it is all that you need you can use a singleton session bean instead of a stateless session bean the stateless session bean was made for this operations that does not require of a state and this operation are going to help you to increase the performance.
If you have a pool with 10 instances you can receive any number of requests but only 10 instances are going to attend them .
Single stateless EJB instance can handle all requests theoretically but too slow.
Performance is main achievement in maintaining stateless EJB pool. Pool saves time in creating the EJBs and acquiring any predefined resources to process the incoming requests. Container guarantees the thread safe behavior so performance is really boosted with multiple ready instances in pool.
Also if the server for a ginen stateless bean is using a pool of 10 instances, is 10 the maximum number of requests it can handle on such a bean ?
With Pool of 10 instances can handle 10 simultaneous requests same time.
Stateless EJB are not state-less. (duh?)
I explain. A stateless EJB has some states, such as a flag for know if the EJB is running/sleeping or if the EJB is loaded and so on. I.e., a stateless EJB has hidden fields.
I am learning about EJB's, so far I have read that multi-threading is not allowed in EJB'S, because it is the container who should care about thread-safety and let the developer only focus in the business logic, so basically that means that EJB ensures that only one thread has access at the same time to a method in a Session bean.
What happens then when we have many users accessing to the same method in a EJB?
Is the container serializing the acceses, or is creating different instances of the bean, one per thread?
Could someone explain me what is the policy about that? Also I am a bit confused, why if multithreading is not allowed, so we cannot create our own threads, why we have this #Asynchronous annotation?
Yes, it creates several instances, and pools them. See the official Oracle documentation:
Because a stateless session bean is never passivated, its lifecycle has only two stages: nonexistent and ready for the invocation of business methods. Figure 22-4 illustrates the stages of a stateless session bean.
The EJB container typically creates and maintains a pool of stateless session beans, beginning the stateless session bean’s lifecycle. The container performs any dependency injection and then invokes the method annotated #PostConstruct, if it exists. The bean is now ready to have its business methods invoked by a client.
At the end of the lifecycle, the EJB container calls the method annotated #PreDestroy, if it exists. The bean’s instance is then ready for garbage collection.
In this book Enterprise JavaBeans 3.1 they talk about EJB objects and implementation objects. I am referring to what I read about stateless session beans:
Once an instance is in the Method-Ready Pool, it is ready to service
client requests. When a client invokes a business method on an EJB
object, the method calll is delegated to any available instance in the
Method-Ready Pool. While the instance is executing the request, is is
unavailable for use by other EJB objects. Once the instance has
finished, it is immediately available to any EJB object that needs it.
Stateless session instances are dedicated to an EJB object only for
the duration of a single method call.
I understand how stateless session beans work but I don't get the difference between a EJB object and stateless session instances?
I thought I made a EJB when I annotate the class with #Stateless for example?
I think it refers the EJB object as i.e. a field in your class which references to the EJB.
It's not an EJB instance - it's a proxy which gives you access to the EJB instance.
Therefore:
public class YourClass {
#EJB
private MyEJB myEjb; // This is a proxy - not a concrete EJB instance
}
During the access, i.e. myEjb.doSomething() the container looks for free EJB instance on which the call will be executed. Another time you invoke myEjb.doSomething() the container might serve you another EJB instance.
Both times, you're using the same myEjb object, while invoked a method on (probably) different EJB instances.
That's how I would understand this paragraph.
The EJB framework provides services like transactionality for your implmenetation classes and this is done by inversion of control.
When you write a session bean, you write only the business logic of the application and the EJB contatiner handles client calls and all middleware stuff. To do so it generates EJB objects augmented with the extra functionality and also containing your business logic.
When you annotate your class, you tell the EJB container to treat it as a basis for EJB objects.
What the excerpt wishes to clarify that stateless session beans do not preserve their 'state' longer than one client request. (Not as stateful beans)
I understand how stateless session beans work but I don't get the difference between a EJB object and stateless session instances?
I think your confusion is in the use of the term 'EJB Objects'
I don't think there's any special term 'EJB Objects'. Maybe you can read
While the instance is executing the request, is is unavailable for use by other EJB objects
as
While the instance is executing the request, is is unavailable for use by any other client
and this
Stateless session instances are dedicated to an EJB object only for the duration of a single method call.
as
Stateless session instances are dedicated to a client only for the duration of a single method call. A second call from the client uses an instance from the free-pool
("client" - can be a servlet, a session bean, an mdb, or a bean managed by CDI, or a POJO which does a JNDI lookup to acquire an ejb reference)
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.