I want to invoke stateless EJB from ReaderInterceptor, WriterInterceptor but I'm not sure is this interceptors can I inject EJB or I need every time lookup EJB?
Specification jax-rs 2.0 say nothing about creating instance for each request. So, it's not thread safe
§6.4 of the JAX-RS 2.0 specification states:
... a single instance of each filter or entity interceptor is instantiated for each JAX-RS application. ...
Therefore your interceptor is by definition a singleton. However, the injection point for your EJB will consist of a proxy that takes care of providing access to an unused instance of the stateless EJB each time it is invoked. It may find it in a pool of pre-created instances or it may just create and initialise a new one.
Additionally, §4.10.13 "Non-reentrant Instances" of the EJB 3.2 specification states that:
The container must ensure that only one thread can be executing a stateless or stateful session bean instance at any time. Therefore, stateful and stateless session beans do not have to be coded as reentrant. ...
In summary, just inject your EJB. The container will look after thread safety issues on your behalf.
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).
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 ;)
Suppose I let my customer reserve seats on a plane using Stateful Session Bean. If the client explicitly calls my Remove method, all of his reservations will be cancelled and the bean is removed afterward.
However, in case the client is idle for some time and the Bean get passivated, if the Bean times out while being passivated, it would be deleted without calling any of my functions. Hence, I'd be very grateful if someone could show me how I can make sure that the reservations would be cancelled if the bean get deleted. If I use the #PreDestroy annotation, will it solve this problem?
Best regards,
James Tran
It is quite possible for the #PreDestroy method to not be invoked. The EJB 3.1 specification, explicitly states this:
4.6.3 Missed PreDestroy Calls
The Bean Provider cannot assume that the container will always invoke
the PreDestroy lifecycle callback interceptor method(s) (or ejbRemove
method) for a session bean instance. The following scenarios result in
the PreDestroy lifecycle callback interceptor method(s) not being
called for an instance:
• A crash of the EJB container.
• A system exception thrown from the instance’s method to the container.
• A timeout of client inactivity while the instance is in the passive state. The timeout is specified by the Deployer in an EJB container implementation-specific way.
The specification also details how resources may be removed if the #PreDestroy method is not invoked in such scenarios:
For example, if a shopping cart component is implemented as a session
bean, and the session bean stores the shopping cart content in a
database, the application should provide a program that runs
periodically and removes “abandoned” shopping carts from the database.
In your case, it would depend on how you are storing the state of your reservations. If they are persisted in the database, then I would suggest employing the same approach as mandated in the specification. You could use the EJB Timer service, to perform this activity periodically, or use a scheduler like Quartz. Note, that it is imperative to distinguish between the contents of passivated session bean instances that no longer exist, and those that will be made ready once again.
A passivated bean will get destroyed on timeout and hence any method annotated with #PreDestroy will do what you are looking for.
While A is active, A's instance of the Stateful bean will not be shared with B until A's instance is destroyed. See the diagram on this article for further reading
Yes it should. The method annotated with #PreDestroy will be called prior to bean removal (even if i times-out in the passivated state)
Are Session Beans (stateless session beans, stateful session beans) Synchronized?
Only one thread at a time will be accessing your beans. It is up to the application server to manage this. So you should not be using synchronized from within your beans. This is why a non-threadsafe like EntityManager can be an instance value and not have synchronization issues.
Stateless beans:
Every thread/request will get different instance of EJB from pool. SLB should not hold any user session data, any state. The same code may be executed in parallel. One instance is accessed by one thread at a time.
Statefull beans are synchronized for user session. Every user will get own session scoped instance. Second thread/request will wait until the first thread finishes. Statefull EJB can hold user specific data. One user cannot execute same code in parallel. Different users may execute same code in parallel.
If accessing a resource that does not allow parallel access use Singleton EJB. As name implies there is only one instance. By default EJB Singleton can be accessed only by one thread (Container Managed Concurrency and #Lock(WRITE)).
Stateless/Stateful session beans are thread safe. Because each request will get a dedicated instance of the bean and so it doesn't need to be synchronized.
Singleton session beans are shared and needs to be synchronized either by the container (Container Managed Concurrency - CMC) or by the user (Bean Managed Concurrency - BMC).
Very True thing about EJB beans is that once you have created EJB 3.0 beans then the methods of the EJB is by default Synchronized.
e.g.
#Statelss
Class EJBclass {
void someMethod(){
}
}
now if you will make this someMethod Synchronize it will show Error like it is can not be Synchronize at this level as it is synchronized.
EJB 3.0 Beans are smart and performance is good.
Enterprise java beans are not synchronized . As session beans are maintained by ejb container so you have to implement synchronization logic in application level.
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.