Java: MDB and Spring's SingletonBeanFactoryLocator - java

In a code base that I've inherited, there's an MDB which is calling SingletonBeanFactoryLocator().getIntance().useBean() to get a factory reference in its ejbCreate(), and then getting a specific bean from this factory and storing it as an MDB instance variable. (The factory is of type 'ClassPathXmlApplicationContext').
The confusing part is: after that bean is obtained, it's calling 'release()' on this factory reference in that same ejbCreate().
Now, this MDB is pooled with poolsize 'x' and what I've observed is, beans defined in the context xml are getting created 'x' number of times. So my guess is, every time the 'ejbCreate()' executes, it's creating a context and its beans afresh.
I checked Spring doc for 'release() above which says:
In an EJB usage scenario this would normally be called from `ejbRemove()` and `ejbPassivate()`.
So here're my questions:
1) is it really creating a new context and new beans everytime ejbCreate() is called?
2) if yes, what happens to the context/beans created in the previous call (e.g. if the beans are singleton themselves, will they be destroyed)?
3) is this the right way to use SingletonBeanFactoryLocator (possibly for thread safety issues) in the context above?
4) if not, what is the right way to use it?
EDIT: one possibility I can think of is to make the concerned beans prototype to make each MDB instance thread-safe, so there's no need to release and recreate the context. Awaiting other comments/suggestions.

Yes
Nothing happens. The same objects will still be in the same MDBs. The MDB doesn't care and Spring is out of the picture at this point.
That really depends on the use circumstances. If you just use Spring to assemble objects and every MDBs should have it's own instances then the answer is yes.
Depending on the use case SpringBeanAutowiringInterceptor may or may not be a better alternative.
Prototype can be tricky. You have to understand your beans and the consequences well to make it do what you expect. That's why it's generally best to make spring beans stateless.
Update:
There is actually a race condition. If the container decides to run the ejbCreate() of two MDBs in parallel then they both will end up sharing the same application context.
Update 2:
I could not find a section that explicitly allows EJB creating through parallel threads but I could also not find a section that explicitly forbids it.
Given the following sections from the spec I assume it would be in the spirit of the spec to do it.
2.4.2 Message-Driven Objects
A typical EJB container provides a scalable runtime environment to execute a large number of mes- sage-driven objects concurrently.
5.2 Goals
A further goal of the message-driven bean model is to allow for the concurrent processing of a stream of messages by means of container-provided pooling of message-driven bean instances.
5.4 Protocol Between a Message-Driven Bean Instance and its Container
It is the container’s responsibility to ensure that the message-driven bean comes into existence when the container is started up and that instances of the bean are ready to receive an asynchronous message delivery before the delivery of messages is started.
5.4.11 Concurrency of Message Processing
A container allows many instances of a message-driven bean class to be executing concurrently, thus allowing for the concurrent processing of a stream of messages. No guarantees are made as to the exact order in which messages are delivered to the instances of the message-driven bean class, although the container should attempt to deliver messages in order when it does not impair the concurrency of mes- sage processing.

Related

synchronized method in stateless session bean not working as expected in glassfish

I have a war file deployed in glassfish. We have some stateless session beans and we have 1 synchronized method in it.
However, I am noticing that more than 1 thread is able to enter the synchronized method concurrently. Is it possible that glassfish is instantiating 2 instances of this bean class? Is there any way around this?
Yes, of course it's possible. The spec even mandates that concurrent calls are handled by different instances.: this is one of the services offered by the container: it makes sure that concurrent calls are handled concurrently, and not sequentially, and you're free to implement your sesssion bean without caring about thread-safety (for example, by using instance variables), because the container takes care of it.
What you want is a singleton.

spring mvc declaring all beans singleton

I have this new mvc project where all beans are default scoped(no prototype or session).
with single application context.
i want to know
by making all beans to be default scoped are we trying to achieve the whole application to be run in single thread?
if so will that make each httprequest(from multiple or same sessions) to be queued until the previous one completes?How to avoid such scenario any advice or link would be helpful.
I am relatively new to spring and java development.
Because Spring beans are typically stateless, you can safely call them from multiple threads. That's how your application works: there is only one instance of every controller, service, DAO, etc. But your servlet container (through Spring) calls these beans from multiple threads - and it's completely thread safe.
In fact in plain servlets the situation is the same - there is only instance of each servlet and it can be accessed by infinite number of threads. As long as this servlet is stateless or properly synchronized.
Do not confuse Spring with stateless session beans in ejb that are pooled and each client gets its own instance from the pool.1
1 - In fact that's a bit dumb - since the beans are stateless by the definition, there is no point in pooling them and preventing concurrent access...
Singleton means that the there will be only one instance of each bean. Generally, such beans are processing elements that carry no state. The methods called on them are passed the context which contains the inputs to work on. Hence the method calls on such singleton beans are inherently thread-safe.

With default bean scope as singleton, isn't it going to be bad when concurrent calls occur?

I have declared a Spring bean, which polls my email server every so and so seconds. If there is mail, it fetches it, and tries to extract any attached files in it. These files are then submitted to an Uploader which stores them safely. The uploader is also declared as a Spring bean. A third bean associates the email's sender with the file's filename and stores that in a DB.
It turned out that when a few people tried to send emails at the same time, a bunch of messy stuff happened. Records in the DB got wrong filenames. Some did not get filenames at all, etc.
I attributed the problem to the fact that beans are scoped to singleton by default. This means that a bunch of threads are probably messing up with one and the same instance at the same time. The question is how to solve this.
If I synchronize all the sensitive methods, then all threads will stack up and wait for each other, which is kind of against the whole idea of multithreading.
On the other hand, scoping the beans to "request" is going to create new instances of each of them, which is not really good either, if we speak about memory consumption, and thread scheduling
I am confused. What should I do?
Singleton-scoped beans should not hold any state - that solves the problem usually. If you only pass data as method parameters, and don't assign it to fields, you will be safe.
I agree with both #Bozho and #stivio answers.
The preferred options are to either pass store no state in a singleton scoped beans, and pass in a context object to the methods, or to use a prototype / request scoped beans that get created for every processing cycle. Synchronization can be usually avoided, by choosing one of these approaches, and you gain much more performance, while avoiding deadlocks. Just make sure you're not modifying any shared state, like static members.
There are pros and cons for each approach:
Singlton beans are act as a service-like class, which some may say are not a good Object-Oriented design.
Passing context to methods in a long chain of methods may make your code messy, if you're not careful.
Prototype beans may hold a lot of memory for longer than you intended, and may cause memory exhaustion. You need to be careful with the life cycle of these beans.
Prototype beans may make your design neater. Make sure you're not reusing beans by multiple threads though.
I tend to go with the service approach in most simple cases. You can also let these singleton beans create a processing object that can hold it's state for the computation. This is a solution that may serve you best for the more complexed scenarios.
Edit:
There are cases when you have a singleton bean depending on prototype scoped bean, and you want a new instance of the prototype bean for each method invocation. Spring supplies several solutions for that:
The first is using Method Injection, as described in the Spring reference documentation. I don't really like this approach, as it forces your class to be abstract.
The second is to use a ServiceLocatorFactoryBean, or your own factory class (which needs to be injected with the dependencies, and invoke a constructor). This approach works really well in most cases, and does not couple you to Spring.
There are cases when you also want the prototype beans to have runtime dependencies. A good friend of mine wrote a good post about this here: http://techo-ecco.com/blog/spring-prototype-scoped-beans-and-dependency-injection/.
Otherwise just declare your beans as request, don't worry about the memory consumption, the garbage collection will clear it up, as long there is enough memory it won't be a performance problem too.
Speaking abstractly: if you'e using Spring Integration, then you should build your code in terms of the messages themselves. Eg, all important state should be propagated with the messages. This makes it trivial to scale out by adding more spring Integration instances to handle the load. The only state (really) in Spring Integration is for components like the aggregator, which waits and collects messages that have a correllation. In this case, you can delegate to a backing store like MongoDB to handle the storage of these messages, and that is of course thread safe.
More generally, this is an example of a staged event driven architecture - components must statelessly (N(1) no matter how many messages) handle messages and then forward them on a channel for consumption by another component that does not know about the previous component from which the message came.
If you are encountering thread-safety issues using Spring Integration, you might be doing something a bit differently than intended and it might be worth revisiting your approach...
Singletons should be stateful and thread-safe.
If a singleton is stateless, it's a degenerate case of being stateful, and thread-safe is trivially true. But then what's the point of being singleton? Just create a new one everytime someone requests.
If an instance is stateful and not thread-safe, then it must not be singleton; each thread should exclusively have a different instance.

multi threaded servlet; single threaded ejb

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.

Why stateless session beans are single threaded?

As per my understanding stateless session beans are used to code the business logic. They can not store data in their instance variables because their instance is shared by multiple requests. So they seem to be more like Singleton classes. However the difference is contain creates (or reuses from pool) the separate instance of stateless session beans for every request.
After googling I could find the reasoning that the Java EE specification says they are suppose to be single threaded. But I can't get the reason why the are specified to be SINGLE THREADED?
The SLSBs are single threaded because of the TX Context, Principal is associated with a bean instance when it is called. These beans are pooled and unless the max pool size is reached are processed in separate threads ( Vendor dependent).
If SLSBs were designed thread safe every call would have looked like a servlet doGet/Post with request info containing Tx Context , Security Context info and etc. So at least the code looks clean (developer dependent).
The primary reason stateless session beans are single threaded is to make them highly scalable for the container. The container can make a lot of simplifying assumptions about the runtime environment. A second reason is to make life easier for the developer because the developer doesn't have to worry about any synchronization or re-entrancy in his business logic because the bean will never be called in another thread context.
I remember the reasoning being discussed in the reviews of the original EJB 1.0 specification. I would look at the goals section of the specification. See http://java.sun.com/products/ejb/docs.html for the list of specifications.

Categories