Stateless beans in Java do not keep their state between two calls from the client. So in a nutshell we might consider them as objects with business methods. Each method takes parameters and return results. When the method is invoked some local variables are being created in execution stack. When the method returns the locals are removed from the stack and if some temporary objects were allocated they are garbage collected anyway.
From my perspective that doesn’t differ from calling method of the same single instance by separate threads. So why cannot a container use one instance of a bean instead of pooling a number of them?
Pooling does several things.
One, by having one bean per instance, you're guaranteed to be threads safe (Servlets, for example, are not thread safe).
Two, you reduce any potential startup time that a bean might have. While Session Beans are "stateless", they only need to be stateless with regards to the client. For example, in EJB, you can inject several server resources in to a Session Bean. That state is private to the bean, but there's no reason you can't keep it from invocation to invocation. So, by pooling beans you reduce these lookups to only happening when the bean is created.
Three, you can use bean pool as a means to throttle traffic. If you only have 10 Beans in a pool, you're only going to get at most 10 requests working simultaneously, the rest will be queued up.
Pooling enhances performance.
A single instance handling all requests/threads would lead to a lot of contention and blocking.
Since you don't know which instance will be used (and several threads could use a single instance concurrently), the beans must be threadsafe.
The container can manage pool size based on actual activity.
The transactionality of the Java EE model uses the thread context to manage the transaction lifecycle.
This simplification exists so that it is not necessary to implement any specific interface to interact with the UserTransaction object directly; when the transaction is retrieved from the InitialContext (or injected into the session bean) it is bound to a thread-local variable for reuse (for example if a method in your stateless session bean calls another stateless session bean that also uses an injected transaction.)
Life cycle of the Statelesss session beans are Doesnot exist, Passive and MethodReady(Passive or Inactive) state.To optimize on perormance, instead of traversing the bean all through from create to method ready state, container manages the bean between active and passive states through the container callbacks - ejbActivate() and ejbPassivate() there by managing the bean pool.
sreenut
Methods by nature ARE THREAD SAFE (including static). Why? Simple, because every variable inside the method is created in the stack memory, i.e. every variable used inside the method is created per call (it's not shared). However, parameters aren't part of the stack.
However, a method is unsafe if it uses an unsafe variable:
a) calling a static field or variable. However, it happens in every single case.
b) calling a resource that it's shared. Such as the EntityManager.
c) passing a parameter that is not safe.
Related
Consider a stateless EJB
from ejb 3.1 spec
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
So a Stateless seession bean can "serve" at most one request at a time,
this is usually implemented by the container managing a pool of beans.
The great goal of all this is Thread safety.
My question is why do we need this form of thread safety ?
I mean Spring beans are singleton and not thread safe (they can serve any number of request at a time) and we have no problem with that.
You need that form of thread safety if the stateless session bean has member variables that are themselves not thread safe (e.g., a SAXParser). However, since stateless session beans don't have client affinity like stateful session beans, the use cases are admittedly relatively rare, and the servlet programming model seems to have shown that this level of protection is probably not necessary, so if you don't need the thread safety then as of EJB 3.1, you can use a singleton session bean with bean-managed concurrency.
The thread safety restriction also gives some additional freedom to the EJB container for optimization. For example, if the EJB container knows that only one thread at a time can be using a stateless session bean, then it can manipulate the state of injected objects at method entry/exit so that those objects don't need use ThreadLocal (e.g., UserTransaction or SessionContext).
Message-Driven Bean Class
the requirements of a message-driven bean class:
It must not define the finalize method.
What is the reason for above requirement ?
If you look in the EJB spec, you will see that it is a requirement for all types of EJB.
http://download.oracle.com/otndocs/jcp/ejb-3.1-pfd-oth-JSpec/
I can't find a definitive answer but looking on various Java forums over the last 13 years, you can see answers consistently saying that, because the container will decide the life-cycle of the EJB, the finalize may never be called (or called when you don't expect) and it would there be dangerous to use it.
https://community.oracle.com/thread/1582366
The reason is that the bean lifecycle is managed by a container (either EJB, CDI or different one) so you should use methods annotated with #PreDestroy to do your cleanup when the bean is going to be disposed. Remember that calling of finalize during object disposal is not guaranteed by JVM so you should never use it even in Java SE environment (Java doesn't have concept of destructors like in C++).
An MDB is not garbage collected unless it fails by number of times configured in the server. And so, this method may never be called at all since MDBs are pooled in the MDB pool and just reused as needed. Since finalize method is called by the GC, then it's rational that you should not define it in your MDB since all it's life cycle is managed by the EJB container. You won't get any exception if you overridden the method since it's already inherited from the Object class, but it's unpredictable when will the code inside it be called. Also, it will be too late to access any resources in the MDB, since the EJB container would have already done it's cleaning job of closing connections and so forth
I am using a Service Locator implementation which caches the result of javax.naming.Context#lookup call, and maps it to the requested EJB interface, so all subsequent requests (for the same EJB) after the first one, return the cached instance.
My concerns are:
Since the same instance is used, there is no utilization of the
server EJB pool which would serve multiple simultaneous requests
with multiple EJBs (unless the underlying server logic somehow makes
use of the EJB pooling)
Stateless and stateful EJBs are thread safe, but since, again,
only one instance per EJB class is used, and EJB has EntityManager
injected via #PersistenceContext, I assume that means that multiple
threads could be using the same EntityManager instance (not just the
persistence context), which definitely is not thread-safe
Do you think that it's best not to use caching in the Service Locator, or that my concerns are unjustified regarding EJB behavior?
What you get from the lookup operation (through the JNDI service) is an object called Stub and him is not fixed with any special EJB instance.
Once cached, every time you invoke an EJB service the stub is able to select a different EJB instance from the pool (this apply to stateless); even in a cluster environment, the stub object is able to select an EJB instance from different servers.
Therefore, caching the stub object should not be a problem.
Notice that I'm talking about stateless, I think that caching doesn't make sense to statefull session bean.
The EJB lookup is a time-consuming operation, so caching improves the client performance.
About your comment:
If you were using EntityManager inside a component that is used by multiple concurrent threads like a Servlet, yes, you will have to care about concurrency, but the EJB's Tread Model imply that will not be several thread using the same EntityManager instance at the same time, so the fact that EM is not thread safe doesn't matter.
What concerns me still is the fact that different EJBs are using the
same injected (via #PersistenceContext) EntityManager instance
I think that for simple sceneries the best way to think about it, if as describe here:
The most common pattern in a multi-user client/server application is
entitymanager-per-request. In this model, a request from the client is
send to the server (where the JPA persistence layer runs), a new
EntityManager is opened, and all database operations are executed in
this unit of work. Once the work has been completed (and the response
for the client has been prepared), the persistence context is flushed
and closed, as well as the entity manager object.
This will be more difficult to check ;)
if I understand EJB correctly, #Singleton is actually the same as Singleton in plain Java and also singleton in spring -> one instance, every call goes through the same instance concurrently.
#Stateless declares a bean, that could (but must not) have multiple instance, with the limitation that only one call can be in an instance at the same time. Right sofar?
This remains me on the servlet programming model: in theory servlet containers are allowed to make multiple copies of the servlet, in practice I haven't seen any servlet container to do so.
So assuming I do not have REALLY LIMITED resources like doors, windows or printers in my code (and if I did I could still solve it with queues and stuff), what is the REAL example, where usage of #Stateless is advantageous over usage of #Singleton.
regards
Leon
You can have multiple instances of a stateless bean to increase throughput.
On the other hand there is only one instance of a singleton. The reason for this is normally to share state in application scope, serializes access to resources etc., and this implies locking or synchronization.
So if you are not really having a singleton, then use a stateless bean.
If you have a "stateless singleton", there is no difference. But if you read "singleton", it has a special meaning by convention (= there must be a reason for using the singleton pattern).
Stateless implies that the bean is thread safe. This is because there is no code in the bean that relies on state. This means that running any of its methods will not affect future running of said methods.
An example of a stateless class would a class that does addition and subtraction. All the necessary parameters are passed into the method. Doing an addition or subtraction does not alter the way these methods work at a later call. This implies that you do not need to worry about concurrency with the class.
A singleton is usually used for a class that is very expensive to create such as a Database connection. You do not want every class creating a new Database connection every time they need to use the database so you have it instantiated once at program start up. Being a singleton does not necessarily mean that the class is thread safe (although it absolutely should be).
So Stateless means the class is threadsafe.
Singleton refers to the fact that the class is only created once. While this heavily implies that the class is (AND IT SHOULD BE) thread safe, it does not directly imply it like stateless does.
Is there a request-scoped context for EJB3 session-beans? My environment is Java-EE-5.
This example
#Remote(SessionFacade.class) #Stateless
public class SessionFacadeBean implements SessionFacade {
#EJB
private Other bean;
public void myBusinessMethod() {
// TODO: get or create *myRequestScope*
*myRequestScope*.put("demo", Integer.valueOf( 1 ));
bean.otherBusinessMethod();
sysout(*myRequestScope*.get("demo"));
}
}
#Local(Other.class) #Stateless
public class OtherBean implements Other {
public void otherBusinessMethod() {
// TODO: get or create *myRequestScope*
*myRequestScope*.put("demo", Integer.valueOf( 2 ));
}
}
should always printout "2" when invoking SessionFacadeBean#myBusinessMethod() - irrespective of parallel invocations.
I do not have the luxury of using CDI. And, it should also work independently of transaction propagation (so JCA is also not an option).
Stateless EJBs, are their name suggests do not store state, so there is no concept of request-scope. There is a session scope that is limited to the current runtime session context, where you cannot store state as well, so that rules out any option of storing state within the bean or within the container.
You might find some luck by using ThreadLocal variables, but this as the name suggests, is scoped to the current thread of execution. Going by your posted code, this appears to be what you would want. The problem with this approach is that,
Thread objects are simply not destroyed once the EJB method has completed execution; they are returned to the container's thread pool. Therefore, if you read the ThreadLocal value in a different context of execution, you will find the value of the previous execution context that used the same thread. In other words, ensure that your application always puts values in the ThreadLocal object before reading them.
Additionally, free any ThreadLocal objects once you do not require them, otherwise you would have a memory leak on your hands.
Is there a request-scoped context for stateless session-beans?
Short answer is No.
The long answer is: You need some context to share data between invocations of your business methods. This could be a design issue. Requestscope is a concept of web-tier.
In the Web-tier the request,page,session and application scope is implemented as a Hashmap. So you could pass a reference to a Hashmap as context to share all data.
Another approach could be to use a singleton (which needs to be shared between nodes e.g. using ehcache).
Migrate to EJB 3.1 and use #Singleton
Consider to use stateful Beans and put your request-scope into the beans session scope which could be removed after you leave the request scope.