am going through enterprise session bean material.i have doubts regarding below oints :-
1) lets say we mentioned the pool size as 50 for some statful session bean. Different 50 clients use them .
so now all the 50 beans maintain some state. At what point of time will these states be removed so that
if 51th clien ask for bean it does not get any previous spoilt state.?
2) lets say we mentioned the pool size as 50 for some stateless session bean and all are in use at some
point of time. If 51th client comes and ask for a bean, will that wait till some bean become free
or create new bean instance?
Stateful session beans are not normally pooled. It's possible, but their state makes them less ideal to pool as the client expects a fresh bean when obtaining a reference.
For stateless beans, yes the 51st client will have to wait. This is normally a good thing since it automatically moderates the resource consumption of your system. Depending on the resources you have, your workload and the amount of work being to in a single call to a ssb, you might want to tune the size of your pool.
As bkail states the pooling semantics of #Stateless beans are vendor-specific. That said in EJB 3.1 we added the #AccessTimeout annotation which can be used on the bean class or methods of a #Stateless, #Stateful or #Singleton bean.
#AccessTimeout
In a general sense this annotation portably specifies up to how long a caller will wait if a wait condition occurs with concurrent access. Specific to each bean type, wait conditions will occur when:
#Singleton - an #Lock(WRITE) method is being invoked and container-managed concurrency is being used. All methods are #Lock(WRITE) by default.
#Stateful - any method of the instance is being invoked and a second invocation occurs. OR the #Stateful bean is in a transaction and the caller is invoking it from outside that transaction.
#Stateless - no instances are available in the pool. As noted, however, pooling sematics, if any, are not covered by the spec. If the vendor's pooling semantics do involve a wait condition, the #AccessTimeout should apply.
Usage
The #AccessTimeout is simply a convenience wrapper around the long and TimeUnit tuples commonly used in the java.util.concurrent API.
import java.util.concurrent.TimeUnit;
#Target({METHOD, TYPE})
#Retention(RUNTIME)
public #interface AccessTimeout {
long value();
TimeUnit unit() default TimeUnit.MILLISECONDS;
}
When explicitly set on a bean class or method, it has three possible meanings:
#AccessTimeout(-1) - Never timeout, wait as long as it takes. Potentially forever.
#AccessTimeout(0) - Never wait. Immediately throw ConcurrentAccessException if a wait condition would have occurred.
#AccessTimout(30, TimeUnit.SECONDS) - Wait up to 30 seconds if a wait condition occurs. After that, throw ConcurrentAccessTimeoutExcpetion
No standard default
Note that the value attribute has no default. This was intentional and intended to communicate that if #AccessTimeout is not explicitly used, the behavior you get is vendor-specific.
Some vendors will wait for a preconfigured time and throw javax.ejb.ConcurrentAccessException, some vendors will throw it immediately. When we were defining this annotation it became clear that all of us vendors were doing things a bit differently and enforcing a default would cause problems for existing apps.
On a similar note, prior to EJB 3.0 there was no default transaction attribute and it was different for every vendor. Thank goodness EJB 3.0 was different enough that we could finally say, "For EJB 3.0 beans the default is REQUIRED."
Related
Getting following exception while reading a method from EJB singleton bean. Even though 60 seconds time out set, exception shown 5000MILLISECONDS. How to increase this time limit?
Caused by: javax.ejb.ConcurrentAccessTimeoutException: WFLYEJB0241:
EJB 3.1 PFD2 4.8.5.5.1 concurrent access timeout on TestBean- could
not obtain lock within 5000MILLISECONDS
Here is timeout setting on bean:
#AccessTimeout(value = 60, unit = TimeUnit.SECONDS)
#Lock(LockType.READ)
public class TestBean {
The Singleton bean, as a definition, can only be instantiated once. It means that by default a #lock ("write") is set in the singleton each time that a method of it is called.
All requests are gonna be serialized by the EJB container if a method of the bean is already called.
The time starts running when the request is serialized. The #AccessTimeout is referred to this time. If an asynchronous request is not completed yet and the time that you set in the #AccessTimeout is already passed, the exception is thrown. Some EJB Containers use their own default value, and in your case, the EJB CONTAINER for wildfly is the one that appears in the error.
So to solve your problem is going to depend on what you want to do, and in each case, there are a lot of possible solutions, but if you just want to avoid this time, you should use the annotation like this:
#AccessTimeout (0), this means that the request cannot be serialized, and it must be executed immediately if the singleton is free, otherwise, it will be lost.
My recommendation is to pass this concurrency handling to a methodlevel, so you can manipulate the bean easily.
#WebListener
public class AllRequestsWebListener implements ServletRequestListener {
#Inject HttpRequestProducer producer;
public void requestInitialized(ServletRequestEvent sre) {
producer.requestInitialized(sre);
}
}
...
#RequestScoped
public class HttpRequestProducer {
...
}
I don't know howto inject request-bean as method-parameter and therefore I can guess that it will work properly when Request-bean injection is threadLocal. Can someone explain me how it's implemented in a thread-safe manner?
What you have injected in your bean is a proxy representing the real deal. The proxy will always forward the invocation to the correct bean
Intuition based answer
I believe it is thread safe, as request scope is thread safe (session and above are not, as a user can open multiple browser sessions and use the same session ID)
I tested it, although it's empiric evidence, but the injected HttpRequestProducer gets a new instance each request.
Note that the requestInitialized and requestDestroyed can be (and in practice are) different threads, so I will investigate further if you intend to use the same injected object on both methods.
Specs backed answer
The hard part was to find hard evidence for this claim in the specs.
I looked into the CDI spec and couldn't quickly find conclusive evidence that a #RequestScoped object is thread safe (e.g. using thread local) however I assume that a #RequestScoped bean is using the same scope as the scoped beans in Java EE 5: (see here)
In there this clause is interesting:
Controlling Concurrent Access to Shared Resources In a multithreaded
server, it is possible for shared resources to be accessed
concurrently. In addition to scope object attributes, shared resources
include in-memory data (such as instance or class variables) and
external objects such as files, database connections, and network
connections.
Concurrent access can arise in several situations:
Multiple web components accessing objects stored in the web context.
Multiple web components accessing objects stored in a session.
Multiple threads within a web component accessing instance variables.
A web container will typically create a thread to handle each request.
If you want to ensure that a servlet instance handles only one request
at a time, a servlet can implement the SingleThreadModel interface. If
a servlet implements this interface, you are guaranteed that no two
threads will execute concurrently in the servlet’s service method. A
web container can implement this guarantee by synchronizing access to
a single instance of the servlet, or by maintaining a pool of web
component instances and dispatching each new request to a free
instance. This interface does not prevent synchronization problems
that result from web components accessing shared resources such as
static class variables or external objects. In addition, the Servlet
2.4 specification deprecates the SingleThreadModel interface.
So in theory, it seems that the object itself is going to have one instance per request thread, however I couldn't find any hard evidence that this is supported.
I am new to server side coding and JSP/servlets. I have a code which has 3 classes. 1st is a Serv class inherited from java httpservlet. In this i have doPost() method implemented. In doPost() i use object of the 2nd class ResourceClass. ResourceClass is a singleton class. Hence essentially to use any method is do something like ResourceClass.getInstance().readResource();
Now readResource furthur uses Java Native access library to read a resource from disk. Now my question is Since as i understand if 1000 clients connect to my server(Apache Tomcat) for each new request i will have a new servlet serving the request. But all these servlets will essentially use the same singleton object. Hence will this reading be thread safe.
I do not change any internal state. So i think it wont effect my output hence the whole stuff is Idempotent. But will all these requests be queued making the singleton class object a bottleneck. Or will each servlet has its own copy.
Also if i change the Resource state then in that case will it be thread safe.
First of all, you won't have a new servlet for each request. The same, unique instance of servlet will be used to concurrently handle all the requests. The servlet is also a singleton: the web container instantiates only one instance.
You say that the requests to your ResourceClass singleton will be queued. They won't, unless you mark the method as synchronized or use some other locking mechanism. If you don't, then the threads will invoke your singleton method concurrently.
Whether it's thread-safe or not is impossible to say without seeing the code of your singleton and the code of the JNI library. The fact that it's read-only is a sign that it could be thread-safe, but it's not guaranteed.
In a Java EE server, you only have 1 instance of each servlet.
On the other hand, each http request is processed by the server in its own thread.
There is one instance of ResourceClass because it's a singleton so you will have a bottleneck if the readResource() method is synchronized.
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.