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)
Related
I have been studying ejb recently and I am also reading about the timer service as well, but even though I have read about Stateless, Stateful and Singleton types of Session Beans, I still have some trouble to figure out what makes the Timer Service have a multiple instance attribute.
I have seen some examples around, and even the simplest ones use the Singleton Session Bean, so, If I were to write a simple program to test it, would it be ok to use a Stateless Bean or is it recommended to use a Singleton anyway? Also, if possible, can I have a case where a Stateless would not be optimal?
Use a singleton if you want to ensure that all timeout callbacks are invoked on the same underlying bean instance. This is important if you want to maintain state in the bean instance itself, and you want to ensure that only one timeout callback can be invoked at a time (by default, the timeout callback will use the singleton's concurrency management settings, which by default is container-managed with a write lock, so only one method on the singleton can be invoked at a time).
Use a stateless if you want to allow multiple timeout callbacks to be invoked at once. The EJB container will create new bean instances if there are multiple timeout callbacks happening concurrently.
If you want to configure a non-persistent timer to begin running when the application begins running, then you can either use the #Schedule annotation on either a stateless or singleton bean, or you can use an #Singleton #Startup bean with an #PostConstruct (and if you want the stateless behavior, you can inject the stateless bean into the stateless bean and invoke a createTimer on the stateless session bean during startup).
The reasons it uses singletons are at least 2 fold:
1.
only singletons have the capabilities of start up initialization. That means, you are able to register your timer services when your application starts.
2.
if it were to use stateless beans, then a new timer service will be registered with every stateless bean setup to serve a request. A singleton guarantees that only one of a kind of your timer is registered. Imagine a contention or integrity issues, or money losses, were you to inadvertently use a timer in a stateless bean and then more than 1 is created at more or less the same time to serve requests.
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.
a stateful will always serve the SOME client, this is the EJB doc says.
In a web application, we use cookie or jsession to know that some client is a prev client.
How the stateful ejb/container knows that some client is the prev client ?
How the stateful ejb/container knows that some client is the prev
client ?
It doesn't. The client has to hold a reference to the stateful EJB along all the invocations of a stateful conversation.
The fact that makes an EJB stateful is it's ability to hold state during many invocations done by the same client, not it's (inexistent) ability to recognize a client that made an invocation previously.
For a stateless EJB you can also hold a reference, but that reference does not guarantee to hold the state between two invocations.
I quote from http://docs.oracle.com/javaee/6/tutorial/doc/gipjg.html
A stateless session bean does not maintain a conversational state with
the client. When a client invokes the methods of a stateless bean, the
bean’s instance variables may contain a state specific to that client
but only for the duration of the invocation. When the method is
finished, the client-specific state should not be retained. Clients
may, however, change the state of instance variables in pooled
stateless beans, and this state is held over to the next invocation of
the pooled stateless bean. Except during method invocation, all
instances of a stateless bean are equivalent, allowing the EJB
container to assign an instance to any client. That is, the state of a
stateless session bean should apply across all clients.
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;
}
}
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.