Is it okay to have a synchronized block in a stateless EJB in EJB 3.1?
The synchronized block is for renewing a connection on connection errors.
Whenever you make a request. the Container provides you with a new instance of the Bean, or an existing instance from the bean pool. you work with the bean, release it, and then it goes back into the EJB Pool. having said that, I don't believe it's necessary to have the method synchronized, as there won't ever occur a time when two threads are using the same EJB instance.
If you want to work with Singleton Beans, then look into the #LockRead and #LockWrite annotations.
This tutorial is quite helpful.
Related
I want to know what will happen when there are no ejbs available in the pool and a client is trying to access a web service which uses the ejb.
We are receiving a NPE at the line where the ejb instance is used to call a method. Unfortunately I do not have access to the logs right now and I am trying to figure out what is wrong. So I am thinking in all possible ways and this question spawned in my head.
Can anyone please tell me?
What I think is, the web service will not be initialized until an ejb instance is available in the pool. So In this case the request will be queued and after sometime the client will receive a timeout error or appropriate message. Am I right?
P.S
BTW, if it makes any difference, I am injecting the ejb using #EJB annotation.
If you use a reference to a SLSB the initialization is just a proxy, no instance is needed.
At runtime the invocation try to get an instance from the pool, if there are all instances busy it will be blocked for a while (5sec by default) and throw an Exception in case of timeout, otherwise just continue.
If you get a NPE this seems to me a different issue where you can't get a reference.
A stateful bean is different, but I think you don't use that.
I think it should be the same no matter which container you use.
I have been reading lately about safe publication of Java objects (e.g. here: http://shipilev.net/blog/2014/safe-public-construction/).
Until now I was trusting EJB container without questions when relying on container managed concurrency.
Now I'm wondering
1) how an EJB container can make sure that the EJB itself is published safely?
2) how an EJB container can make sure that objects created by its EJBs are published safely (e.g. EJB instance vars)?
E.g. stateless session bean can be accessed by different threads over time (I'm not necesseraly saying simultaneously), so unsafe publication is a potential issue.
For 1), I roughly see possibilities, e.g. by wrapping the EJB and using some volatile accesses to garantuee total order.
For 2), I don't see how EJB container can enforce it.
Maybe it is forbidden by the EJB 3.1 spec to keep instance variables in the EJB if it can be accessed by different threads?
Maybe the statement "don't worry about concurrency in container managed EJB" is not true, and I should use safe publication patterns (including volatile and/or final keywords) in the class definitions of the classes used in my EJB instance vars?
I'm surpirsed I missed this fundamental problemacy for that many years as a Java developer.
Regards,
Lars
If an EJB container is reusing instances, it must store them in a thread-safe object pool, which must use some synchronization (synchronized, compare-and-swap, etc.), which will ensure that everything written by the first thread will "happen-before" everything that happens on the second thread. EJB developers do not need to worry about synchronization (unless they're using singleton session beans with bean-managed concurrency or the EJB is going outside the scope of the EJB spec by storing data in static variables).
Hello everybody I am newbie for EJB component technology and i have to learn this in order to prepare my colloquium exam. I am not sure I can understand all details of the life cycle.
The life cycle includes these steps:
-The client request to EJB Container ( but how this request could be done ? Is the location of the request I mean that remote " outside of the EJB container" or local" inside of the EJB container" is important or not?)
-By depending on the request one bean instance is created in the pool and return to the client and after use from the client it returns again in the pool ( depending on the bean type(?).
I think this scenario appropriate for the stateless session bean but I am not sure. Because in stateful session bean scenario there is no pool.)
Advance thanks for all helps.
"client" in this context just means "application code that will lookup/inject an EJB and call EJBs"; it is the opposite of "application code of the EJB itself" (which does not have a well-defined term; I've seen the term "EJB" overloaded for this meaning, or "service", etc.). Local EJB vs remote EJB is not relevant in this context, even though "client" also has a well-defined meaning for remote.
Yes, pooling of session beans refers only to stateless session beans. Stateful and singleton session beans do not have a pool. Message-driven beans can also be pooled, but they are not directly invoked by a client per se, even though there can be a logical client; e.g., the one that send the JMS message. (Entity beans can also be pooled, but they're not really relevant these days.)
Normally Servlets are initiated just once and web container simple spawns a new thread for every user request. Let's say if I create my own web container from scratch and instead of Threads, I simply create Servlets as Singleton. Will I be missing anything here? I guess, in this case, the singleton can only service one user request at a time and not multiple.
Normally Servlets are initiated just once and web container simple spawns a new thread for every user request.
The first statement is true, but the second actually not. Normally, threads are been created once during applications startup and kept in a thread pool. When a thread has finished its request-response processing job, it will be returned to the pool. That's also why using ThreadLocal in a servletcontainer must be taken with high care.
Let's say if I create my own web container from scratch and instead of Threads, I simply create Servlets as Singleton. Will I be missing anything here?
They does not necessarily need to follow the singleton pattern. Just create only one instance of them during application's startup and keep them in memory throughout application's lifetime and just let all threads access the same instance.
I guess, in this case, the singleton can only service one user request at a time and not multiple.
This is not true. This will only happen when you synchronize the access to the singleton's methods on an application-wide lock. For example by adding the synchronized modifier to the method of your servlet or a synchronized(this) in the manager's method who is delegating the requests to the servlets.
JavaEE used to have a mechanism for this - a marker interface called SingleThreadModel that your servlet could implement:
Ensures that servlets handle only one request at a time. This interface has no methods.
If a servlet implements this interface, you are guaranteed that no two threads will execute concurrently in the servlet's service method. The servlet container can make this guarantee by synchronizing access to a single instance of the servlet, or by maintaining a pool of servlet instances and dispatching each new request to a free servlet.
Note that SingleThreadModel does not solve all thread safety issues. For example, session attributes and static variables can still be accessed by multiple requests on multiple threads at the same time, even when SingleThreadModel servlets are used. It is recommended that a developer take other means to resolve those issues instead of implementing this interface, such as avoiding the usage of an instance variable or synchronizing the block of the code accessing those resources. This interface is deprecated in Servlet API version 2.4.
Containers could use this to instantiate a new servlet for each request, or maintain a pool of them, if they chose to.
This was deprecated in Servlet 2.4, for the reasons documented above. Those same reasons still apply to your question.
That's basically it.
I would question the motivations for creating your own container, with so many available for a wide range of purposes.
We all know that in the web tier there is the possibility that only a single instance of a given Servlet exists which services multiple requests. This can lead to threading issues in instance variables.
My question is, is it safe to inject an EJB using the #EJB annotation into a servlet as an instance variable?
My initial instinct would be no, under the assumption that the same instance of the EJB would service multiple requests at the same time. It would seem that this would also be the instinct of a number of other programmers: Don't inject to servlets
However have I jumped to the wrong conclusion. Clearly what is injected into the servlet is a proxy, under the hood does the container actually service each request with a different instance and maintain thread safety? As this forum would suggest: Do inject to servlets
There seems to be a lot of conflicting opinions. WHICH IS CORRECT???
It is safe to inject an EJB in a Servlet as a Servlet instance variable, as long as the EJB is Stateless. You MUST NEVER inject a Stateful Bean in a Servlet.
You must implement your EJB stateless in that it doesn't hold any instance variable which itself holds a stateful value (like Persistence Context). If you need to use the persistence context, then you must get an instance of it IN the methods of the EJB. You can do that by having a PersistenceContextFactory as a EJB instance Variable and then you get an instance of the entity manager from the Factory in the method of the EJB.
The PersistenceContextFactory is thread-safe, thus it can be injected in an instance variable.
As long as you comply to the above mentioned rules, it should be thread-safe to inject a Stateless Bean in a Servlet
Your reference "Don't inject to servlets" mentions nothing about ejbs or #ejb annotation. It talks about not thread safe objects such as PersistenceContext.
Per EJB spec you can access ejbs from variety of remote clients including servlets (EJB 3.0 Specification (JSR-220) - Section 3.1). Injecting ejb using #EJB annotation is a method of obtaining EJB interface via dependency injection (section 3.4.1) which is alternative to looking up ejb objects in the JNDI namespace. So there is nothing special about #EJB annotation with respect to EJBs obtained.
So, based on EJB 3.0 Spec, it's a standard practice to obtain ejbs from servlets using #EJB annotation.
It's a mixed bag.
Stateless session beans may be injected and are safe. This is because even if a single instance of a stub is used, access to the methods will be serialized by the container.
I think what inferreddesign says is not true. It doesn't matter if the stateless session bean uses a persistence context. Only one caller will ever access a single bean instance at the same time, so even though the persistence context is not thread safe, the EJB guards against multiple access to it. Think of it as if every session bean method has the synchronized keyword applied to it.
The main problem with injecting an EJB in a Servlet I think is performance. The single stub instance will become a major area of contention when multiple requests are queuing up while waiting for a session bean method to be executed for them.
I think the simple answer is that you aren't guaranteed that it is safe.
The reason for this is that there is nothing explicit in the EJB specification that says EJB home interfaces have to be thread safe. The spec outlines the behaviour of the server side part only. What you will probably find is that the client skeletons are actually thread safe but you would need to look at how they are implemented by the library you are using. The annotation part will just expand into a service locator so that doesn't buy you anything.