Request scoped context for stateless session beans - java

Is there a request-scoped context for EJB3 session-beans? My environment is Java-EE-5.
This example
#Remote(SessionFacade.class) #Stateless
public class SessionFacadeBean implements SessionFacade {
#EJB
private Other bean;
public void myBusinessMethod() {
// TODO: get or create *myRequestScope*
*myRequestScope*.put("demo", Integer.valueOf( 1 ));
bean.otherBusinessMethod();
sysout(*myRequestScope*.get("demo"));
}
}
#Local(Other.class) #Stateless
public class OtherBean implements Other {
public void otherBusinessMethod() {
// TODO: get or create *myRequestScope*
*myRequestScope*.put("demo", Integer.valueOf( 2 ));
}
}
should always printout "2" when invoking SessionFacadeBean#myBusinessMethod() - irrespective of parallel invocations.
I do not have the luxury of using CDI. And, it should also work independently of transaction propagation (so JCA is also not an option).

Stateless EJBs, are their name suggests do not store state, so there is no concept of request-scope. There is a session scope that is limited to the current runtime session context, where you cannot store state as well, so that rules out any option of storing state within the bean or within the container.
You might find some luck by using ThreadLocal variables, but this as the name suggests, is scoped to the current thread of execution. Going by your posted code, this appears to be what you would want. The problem with this approach is that,
Thread objects are simply not destroyed once the EJB method has completed execution; they are returned to the container's thread pool. Therefore, if you read the ThreadLocal value in a different context of execution, you will find the value of the previous execution context that used the same thread. In other words, ensure that your application always puts values in the ThreadLocal object before reading them.
Additionally, free any ThreadLocal objects once you do not require them, otherwise you would have a memory leak on your hands.

Is there a request-scoped context for stateless session-beans?
Short answer is No.
The long answer is: You need some context to share data between invocations of your business methods. This could be a design issue. Requestscope is a concept of web-tier.
In the Web-tier the request,page,session and application scope is implemented as a Hashmap. So you could pass a reference to a Hashmap as context to share all data.
Another approach could be to use a singleton (which needs to be shared between nodes e.g. using ehcache).
Migrate to EJB 3.1 and use #Singleton
Consider to use stateful Beans and put your request-scope into the beans session scope which could be removed after you leave the request scope.

Related

Can I change spring parameters on execution?

I have an application which uses dynamic consumers. I'm using Spring Framework with RabbitMQ.
I have parameters like concurrentConsumers and maxConcurrentConsumers.
This is a example:
#Bean
public SimpleMessageListenerContainer container(ConnectionFactory connection) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setMaxConcurrentConsumers(8);
container.setConcurrentConsumers(1);
return container;
}
Can I change the values when the application is running? For example, if I want 5 maxConcurrentConsumers instead of 8, can I change the value on a terminal or something like this while the application is running?
Your bean is a singleton and should be stateless (at least, immutable or effectively stateless) to ensure thread-safety and correctness.
As a rule, you should use the prototype scope for all stateful beans and the singleton scope for stateless beans.
Spring documentation
Sometimes, the creation of a bean is quite expensive, so it's more reasonable to construct an instance once and then guarantee that all possible changes made on this object will be permeated in a safe and correct fashion over all its consumers.
I advise building a simple event-driven mechanism.
There are
a MessageListenerContainerEvent extends ApplicationEvent which represents the changes made to the MessageListenerContainer bean;
a MessageListenerContainerChanger implements ApplicationListener<MessageListenerContainerEvent> who is the one listener who modifies the state of the bean, and guarantees that everything works properly;
other listeners who are class that use the bean and are interested in keeping it up-to-date. It's not necessary to send the changes to bean consumers, you could just notify them with no message. For them, it means that some properties of the bean they use locally might be out-of-date.
a publisher which could be an HTTP endpoint, or a #ShellMethod.
It might look too complex, you always can simplify it to
// somewhere in your code
synchronized(bean) {
bean.setConcurrentConsumers(10);
}
but bear in mind the correctness this snippet propagates.

What happens when you hold a reference to a stateless EJB on a long life object?

Just a thought experiment. I know it is absolutely NOT how they are supposed to be used, but I want to know how the system would break or cause problems.
Imagine a session or an application scoped or any other kind of object which lifespan is longer than a request. Which has a #Stateless EJB field, received by constructor or a setter, and holds that reference forever.
What happens to that EJB and the container?
Your "stateless EJB field" is a reference to a Stateless EJB.
However, it does not refer directly to the EJB instance. The referred object is a proxy for the EJB.
Every time you invoke a method through that proxy, the container creates or otherwise acquires a reference to an instance of the EJB and then invokes it. Containers may have a pool of these EJB instances so that it can acquire them quickly. It can do this because they are Stateless after all.
If you have:
public class Foo {
#EJB
private Bar myStatelessEJB;
public void doSomething() {
myStatelessEJB.eat();
myStatelessEJB.something();
}
}
Then each invocation of myStatelessEJB may call a completely different instance of Bar.
Therefore it makes no difference how long you keep the reference to the EJB. The container may forget it completely between calls or it may return it to a pool for other clients.

What is a real use-case for #Stateless over #Singleton in EJB

if I understand EJB correctly, #Singleton is actually the same as Singleton in plain Java and also singleton in spring -> one instance, every call goes through the same instance concurrently.
#Stateless declares a bean, that could (but must not) have multiple instance, with the limitation that only one call can be in an instance at the same time. Right sofar?
This remains me on the servlet programming model: in theory servlet containers are allowed to make multiple copies of the servlet, in practice I haven't seen any servlet container to do so.
So assuming I do not have REALLY LIMITED resources like doors, windows or printers in my code (and if I did I could still solve it with queues and stuff), what is the REAL example, where usage of #Stateless is advantageous over usage of #Singleton.
regards
Leon
You can have multiple instances of a stateless bean to increase throughput.
On the other hand there is only one instance of a singleton. The reason for this is normally to share state in application scope, serializes access to resources etc., and this implies locking or synchronization.
So if you are not really having a singleton, then use a stateless bean.
If you have a "stateless singleton", there is no difference. But if you read "singleton", it has a special meaning by convention (= there must be a reason for using the singleton pattern).
Stateless implies that the bean is thread safe. This is because there is no code in the bean that relies on state. This means that running any of its methods will not affect future running of said methods.
An example of a stateless class would a class that does addition and subtraction. All the necessary parameters are passed into the method. Doing an addition or subtraction does not alter the way these methods work at a later call. This implies that you do not need to worry about concurrency with the class.
A singleton is usually used for a class that is very expensive to create such as a Database connection. You do not want every class creating a new Database connection every time they need to use the database so you have it instantiated once at program start up. Being a singleton does not necessarily mean that the class is thread safe (although it absolutely should be).
So Stateless means the class is threadsafe.
Singleton refers to the fact that the class is only created once. While this heavily implies that the class is (AND IT SHOULD BE) thread safe, it does not directly imply it like stateless does.

EJB and Synchronization

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.

Why pool Stateless session beans?

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.

Categories

Resources