Stateless Session Beans vs. Singleton Session Beans - java

The Java EE 6 Tutorial says:
To improve performance, you might choose a stateless session bean if it has any of these traits:
The bean’s state has no data for a specific client.
In a single method invocation, the bean performs a generic task for all clients. For example, you might use a stateless session bean to send an email that confirms an online order.
The bean implements a web service.
Singleton session beans are appropriate in the following circumstances:
State needs to be shared across the application.
A single enterprise bean needs to be accessed by multiple threads concurrently.
The application needs an enterprise bean to perform tasks upon application startup and shutdown.
The bean implements a web service.
But what to use if:
no state has to be shared across the application
a single enterprise bean could be accessed by multiple threads concurrently
no tasks on startup or shotdown need to be performed
Say for example I have a login service with the following interface:
public interface LoginService {
boolean authenticate(String user, String password);
}
Should it be annotated with #Singleton or #Stateless? What are the benefits of the one and the other? What if LoginService needs to get injected an EntityManager (which would be used concurrently)?
Addition: I'm thinking about the Java EE counterpart of Spring service beans, which are stateless singletons. If I understand that correctly the Java EE counterpart are #Stateless session beans and #Singleton Beans are used to configure the application at startup or cleanup at shutdown or to hold application wide objects. Is this correct?

I would go for Stateless - the server can generate many instances of the bean and process incoming requests in parallel.
Singleton sounds like a potential bottleneck - the default #Lock value is #Lock(WRITE) but may be changed to #Lock(READ) for the bean or individual methods.

according to the ejb 3.1 spec, page 110, chapter 4.8.5 "Singleton Concurrency":
It is legal to store Java EE objects that do not support concurrent access (e.g. Entity Managers, Stateful Session Bean references) within Singleton bean instance state. However, it is the responsibility of the Bean Developer to ensure such objects are not accessed by more than one thread at a time.
and furthermore, according to the hibernate entitymanager documentation
An EntityManager is an inexpensive, non-threadsafe object that should be used once, for a single business process, a single unit of work, and then discarded.
For me, this means, that you should never inject an EntityManager into a singleton EJB. I would use a singleton EJB as a replacement for a stateless EJB only if EVERYTHING I need to implement in this class supports concurrency without the need to do additional locking / synchronization. As you or other programmers might lose this issue sooner or later from your focus, I personally prefer to not use singleton EJBs except for startup-related issues or features that can be implemented as self-contained units - independently of other beans. In that sense, it doesn't seem to be advisable to inject for example Stateless EJBs into Singletons. Doing so raises the question about the point in time, when the container actually performs the injection of the SLSB into the Singleton? According to the EJB 3.1 Spec, chapter 4.8, the dependency injection gets done before the singleton bean instance can be accessed by clients. So the singleton would obviously stick to the same instance of the SLSB, which seems to become a singleton implicitly, but there doesn't seem to be any guarantee for that. At least I couldn't find anything in the specs, so the behavior might be unpredictable or in the best case container-specific, which is not what most people will want.
Thus, I would only inject Singletons into Singletons or Singletons into SLSBs but not vice versa. For the case of an injection of a Singleton into a Singleton, the Spec offers you the opportunity to define the dependencies between the singletons so that the container can initialize them in the correct order (see the ejb 3.1 spec, chapter 4.8.1 concerning the #DependsOn annotation).

#Stateless will allow you to have multiple copies ready for processing within a JVM (as much as memory and pool size allows) where-as #Singleton there's only one copy in a JVM, even if the single one can support multiple concurrent threads running against it.
In terms of performance #Singleton would be better, provided that the resources it uses allow long running access. However, in a distributed environment sometimes bad things occur, e.g. database or network links may fail.
With a #Stateless bean, the access is more short lived. In addition, should there be a failure it will just respawn and try to establish a new connection to the resource. If something happens like that on a singleton, then it's up the the singleton to handle it without requiring an application restart because the #PostConstruct is only called once per JVM.
I would prefer a bit of fault tolerance vs performance for most situations especially on systems I have no control over.

I think Singleton in concurrency usage will not perform worse than SLSB Pool, it might be even better. The only problem is if you want to share something between threads, you need lock it, and that could be a big problem of performance. So in that case, a SLSB Pool perform much better, because it's not 100% singleton, there are more instances, one got locked, the other one comes up. Anyway if the lock is on some resource sharing by all SLSBs, the pool won't help neither.
In short, I think singleton is better than SLSB Pool, you should use it if you can. It's also the default scope for Spring Beans.
I'm not a JavaEE expert, that's just my feeling, please correct me if I'm wrong.

I think you should use Singleton session bean. Because a login service should be a global service and it does not need to store any state for a concrete user or invocation.

If you're sure you're not sharing state between threads, then a Singleton will be fine in which case you should also annotate the class with #ConcurrencyManagement( ConcurrencyManagementType.BEAN ) which will allow multiple threads running at the same time.

you should go for Singleton if you have any resource that is going to remain constant across the application. Like loading some data from some file or reference data which would not change across the application lifecycle. otherwise, go for SLSB. The drawback of SLSB is that multiple objects would be created hence more memory would be occupied.

Imho I would answer like that:
"no state has to be shared across the application" leads me to stateless bean because of the sentence "To improve performance, you might choose a stateless session bean...".
Considering "a single enterprise bean could be accessed by multiple threads concurrently" you would have to use singleton. If I got it right it is not even possible to access a stateless bean's concurrently when properly used.
"no tasks on startup or shotdown need to be performed" would not matter to me. If tasks have to be done to properly setup a bean then they have to be invoked by a #PostActivate method.
I would logically conclude your question what to use to #Singleton since you asked for concurrent access. Of course you will have to manually control snychronisation of accesses on any further resources (which are not EJBs).

Related

Can I pool controllers in a spring mvc application and if so how will it effect the performance?

In spring 3.0 controllers can be created simply by annotating the class as #Controller and is singleton by default.
So to cater many requests container will have only one object of that type.
On the other-hand if it is prototype,then many objects will be created and hence resource utilization will be poor.
Please correct me if I am wrong. My question is can I pool the controllers and if I can, then will it improve the concurrency and throughput?
You are correct that all Controllers are singleton by default.
Unless your Controller is stateful there is no need to have a pool of instances. Your web container will be using a managed pool of Threads to handle requests, each of which can access the Controller at the same time (due to there being no shared state). I would suggest that tuning your web container will give you better results for concurrency and throughput.
If your Controllers are stateful then there is still no need for a pool of instances. Instead you should probably manage the state within Session or Request scoped beans and rely on Spring to inject these into the Controller on each request ensuring that multiple Threads of execution do not interfere with one another.
Given your current level of understanding you should be fairly comfortable with different scopes. I would suggest also reading and understanding how Spring makes use of Proxys to inject scoped beans into Controllers.

Concurrency control with method invocation in EJB bean vs. Spring bean

EJB container serializes all business method invocations by default. And we have a couple of options to change it.
Apply the #Lock(LockType.READ)/#Lock(LockType.WRITE) annotations.
Or set #ConcurrencyManagement(ConcurrencyManagementType.BEAN) annotation on the bean class and use our custom synchronization policy (use syncrnozied blocks or don't use locks at all if bean only reads data, for example). The #Lock annotations is ignored in this case.
My question is how does Spring control it? How does it work be default?
Spring bean may be a stateless bean or may have a state. It can access some resource with read or write operations. And in different situations I need an option to control concurrency.
Could you please explain and compare this aspect of EJB/Spring containers.
EJB declarative concurency management applies only to singleton session beans, see javax.ejb.ConcurrencyManagement API. Regular session beans have no thread safety issues because containter insures that only one thread accesses a bean instance at any given time. As for Spring beans concurrency is not managed by container, programmers themselves should take care of it.

How to create a cross-process Singleton class in Java

Is is possible to create a universal Singleton class, which is, at any given time, only one instance is shared across multiple Java processes?
Multiple Java processes don't share the same virtual machine.
So you would end up with one JVM instance hosting the singleton, then one JVM instance per process which access the singleton using Remote Method Invocation as #Little Bobby Tables suggested.
Anyway consider When is a Singleton not a Singleton:
Multiple Singletons in Two or More Virtual Machines
When copies of the Singleton class run in multiple VMs, an instance is created for each machine. That each VM can hold its own Singleton might seem obvious but, in distributed systems such as those using EJBs, Jini, and RMI, it's not so simple. Since intermediate layers can hide the distributed technologies, to tell where an object is really instantiated may be difficult.
For example, only the EJB container decides how and when to create EJB objects or to recycle existing ones. The EJB may exist in a different VM from the code that calls it. Moreover, a single EJB can be instantiated simultaneously in several VMs. For a stateless session bean, multiple calls to what appears, to your code, to be one instance could actually be calls to different instances on different VMs. Even an entity EJB can be saved through a persistence mechanism between calls, so that you have no idea what instance answers your method calls. (The primary key that is part of the entity bean spec is needed precisely because referential identity is of no use in identifying the bean.)
The EJB containers' ability to spread the identity of a single EJB instance across multiple VMs causes confusion if you try to write a Singleton in the context of an EJB. The instance fields of the Singleton will not be globally unique. Because several VMs are involved for what appears to be the same object, several Singleton objects might be brought into existence.
Systems based on distributed technologies such as EJB, RMI, and Jini should avoid Singletons that hold state. Singletons that do not hold state but simply control access to resources are also not appropriate for EJBs, since resource management is the role of the EJB container. However, in other distributed systems, Singleton objects that control resources may be used on the understanding that they are not unique in the distributed system, just in the particular VM.
Yes, but not without external facilities. The simplest way is to use RMI. Other options include CORBA or Web Services - Just google it up.

java ejb3 #PostConstruct

I am experimenting with EJB3 on JBoss, developing a stateless bean. Basically once the module has been deployed I need to perform some actions related to load application settings.
To do this I've annotated a method as #PostConstruct, which as far as I know from the API instructs the container to invoke it once the bean has been deployed and before get in service. (correct?)
Now, I am confused, because from the log on that method looks like is not simply called after has been deployed but before each exposed method is called.
I only need to call that method once, not every time it receives a call. What would be the best approach?
Thanks in advance
Alessandro Ilardo
A stateless bean should be just that - stateless. Meaning that in use, you should neither be able to tell or to care if the bean was pulled from a pool or constructed on demand for your request. I'm hard-put to envision how a PostConstruct could apply to a stateless environment, since I always use that function to finish building a bean's state.
Apparently, JBoss is either forgoing the pooling of stateless beans and constructing them fresh each time, or, if it is using pooling, treating them like they were reconstructed each time (since they shouldn't be carrying state information). I'm actually a little surprised that it invokes the PostConstruct at all.
First of all PostConstruct is called before first method will be invoked on the bean. If no method will be invoked no post construct ever be called.
Secondly you can execute inverse actions in PreDestory method to remove side effects.
Anyway which kind of action you have to perform?
It is up to the app server to manage the lifecycle of EJBs. It may decide to construct, initialise and tear down beans whenever it sees fit. It may be that each call to your stateless bean is on a fresh instance of the your bean class, although that does seem like an off thing to do.
Is the app server calling the #PostConstruct method multiple times on the same object instance, or on a different instance each time? Try sticking log statements inside the constructor and the #PostConstruct method.
How many SLSB do you have in your pool? Depending on the container the #PostConstruct may not be called until the first client accesses it (not sure about JBoss) so this may be why it looks like it is on every access. It would be interesting to see if it stopped calling your post-construct method after calling your method the number of times equalling your pool size.
If you are performing some expensive actions in your post-construct method then maybe do these in a SFSB at startup and "inject" that SFSB into your SLSB in the post-construct.
PostConstruct gets called before the client runs a biz method. This means that if the bean isn't pooled the container will instantiate the bean, do injection, call the #PostConstruct method, then allow the biz method to run.
In the case of a pooled be then the #PostConstruct method will be run every time the bean is pulled from the pool. With Stateless beans this will be between every method call. With Stateful beans this will be after client lookup or injection.
If you need to run something on application deployment your options will depend on the version of Java EE you have.
For Java EE 6 you can use #Startup on a #Singleton EJB which contains a #PostConstruct method.
For Java EE 5 and previous you'll have to use a ServletContextListener in a web archive. You can have the ServletContextListener call an EJB if you want.
However what might be a more important question is where do you want to load these application settings to? If you are dealing with a non-clustered single JVM configuration then you probably going to want to load them into a Singleton of some type. In Java EE 5- you'll have to implement the singleton design pattern yourself or in EE 6 use the #Singleton EJB type.

Do you really need stateless session beans in this case?

We have a project with a pretty considerable number of EJB 2 stateless session beans which were created quite a long time ago. These are not the first-line beans which are accessed from our client via RMI, rather they are used by that code to perform specific functions. However, I've come to believe that there's nothing to be gained by having them as session beans at all.
They do not need to be accessed via
RMI.
They do not retain any state,
they are just code that was factored
out of the first set of beans to
reduce their complexity.
They don't
have multiple different
implementations which we are swapping
out, each one has been as it was for
years (barring bug fixes and feature
additions).
None of them alter the
transaction that comes into them from the bean calling them
(that is they don't require a new
transaction, not participate in the
existing one, or otherwise change
things).
Why should these not all just be classes with a couple of static functions and no EJB trappings at all?
The only reason I can see is for clustering purposes (if you are doing clustering). That is the hand off to those beans could be on another VM on another machine if clustering is being done right to spread the load around.
That is likely not the case, and the movement to EJB's was just over-engineering. I'm suffering with that too.
Even transactions aren't really enough to justify it, you can have a single EJB that handles the transactions and call the different code through it via a Command type pattern.
There seems to be no reason why they shouldn't just be simple POJO's rather than stateless session beans. I think this is the conclusion that people came to after using EJB 1.x in this manner as well.
It's also the reason why frameworks such as Spring exist as an alternative to EJB's.
I'd say change them over to be just standard POJO's, but make sure you have a safety net of unit and functional tests (which might be a little bit harder with EJB's) to help you.

Categories

Resources