stateless EJB3 bean invoked from request-scoped JAX-RS web service accumulates state - ejb-3.0

I have the following situation: Request-scoped JAX-RS service invokes stateless EJB3 bean and the EJB3 bean retains state between successive invocation of the web service from a client.
Code as follows:
web service
#javax.enterprise.context.RequestScoped
#Path("/actions")
public class CounterFrontEnd {
#EJB
private ICounterService.ILocal counterService;
#GET #Produces("application/text;") #Path("/counter")
public String counter() {
return String.format("%d ", counterService.incCounter());
}
stateless EJB3 bean
#Stateless
#Local (ICounterService.ILocal.class)
#Remote(ICounterService.IRemote.class)
public class CounterService implements ICounterService.ILocal, ICounterService.IRemote {
public int counter = 0;
#Override
public int incCounter() {
return counter++;
}
I then invoke the service with the following python script:
for i in range(100):
os.system( 'curl http://somewhere:8080/counter-ws/rest/actions/counter' )
Surprisingly, the output is:
1 2 3 4 5 ...

This is because the container (happens) to give you the same bean-instance every time, not something you should rely on.
Stateless session-beans should not rely on instance-variables like in your example.
From java ee tutorial: http://docs.oracle.com/javaee/6/tutorial/doc/javaeetutorial6.pdf
Stateless Session Beans
A stateless session bean does not maintain a conversational state with
the client. When a client invokes the methods of a stateless bean, the
bean’s instance variables may contain a state speciic to that client
but only for the duration of the invocation. When the method is
inished, the client-speciic state should not be retained. Clients may,
however, change the state of instance variables in pooled stateless
beans, and this state is held over to the next invocation of the
pooled stateless bean. Except during method invocation, all instances
of a stateless bean are equivalent, allowing the EJB container to
assign an instance to any client. That is, the state of a stateless
session bean should apply across all clients.

Related

How to handle Spring transactions inside coroutines?

It is known that Spring transactions are tied to threads: there are thread locals specific for an ongoing transaction. And transactions know nothing about coroutine context. So what if I would like to call a #Transactional method from inside a coroutine: is it safe?
Imagine we have a method inside JobProcessor bean processing a job list. Each job is processed inside async{}. And I would like to update DB after every successful or failed processing using #Transactional methods of bean JobService.
class JobProcessor {
fun process(jobs: List<MyJob>) =
jobs.map { job ->
async {
try {
....//processing
jobService.success(job)
} catch (t: Throwable) {
jobService.failure(job)
}
}
}
class JobService {
#Transactional
fun success(job: MyJob) {...}
#Transactional
fun failure(job: MyJob) {...}
}
First, please keep in mind that annotating bean methods with #Transactional will not suffice - make sure you enabled declarative transaction handling, e.g. by adding #EnableTransactionManagement to a #Configuration class or by using <tx-annotation-driven /> in XML config.
Regarding your question: There will only be a transactional context while executing Spring bean methods annotated with #Transactional when they are being invoked from a Spring bean outside of their containing class! Declarative transactions in Spring rely on AOP proxy classes being created for the #Transactional annotated classes by Spring. At runtime if a Spring bean A calls a #Transactional method on a Spring bean B, the call will be intercepted by an AOP proxy that transparently spawns a transaction, calls the original method of Spring bean B and commits or rollbacks this transaction afterwards.
Remember: Only external method calls that come in through the proxy will be intercepted – any self-invocation calls, as in your example this.process() calling #Transactional methods this.success() or this.failure() will not start any transaction – even if the method is annotated with #Transactional.

Spring Singleton bean management

There is scenario where we have 50 browsers opened accessing the application , if there is a singleton scoped(meaning one bean per container), then how the singleton bean is shared among all the instance of threads
or if one object is shared to only one browser(client) then all other client will be idle waiting which is bad design
Could some body suggest answer
For stateless beans, having a single instance ("singleton") is fine:
#Component
public class MyManager {
public void doStuff();
}
Any number of clients (browsers) can call doStuff() without impacting each other as long as doStuff() doesn't manage state.
For stateful beans that manage user state, you can use session scoped beans:
#SessionScope
#Component
public class UserPreferences {
private String username;
public setUsername(String username) {
this.username = username;
}
//...
}
The UserPreferences bean is instantiated once per HTTP session. Hence every client (browser) gets its own object.
In both cases one client (browser) does not have to wait until processing has finished for other clients.

Injecting dependencies using an Interceptor

Would it be technically a good and acceptable practice to inject required dependencies using an Interceptor type. For example:
public #interface Inject {
public Class thisType();
}
public class InjectionInterceptor implements HandlerInterceptor {
#Override
public bool preHandle(HttpServletRequest hsr, HttpServletResponse hsr1, Object o) {
HandlerMethod handlerMethod = (HandlerMethod) o;
Class type = handlerMethod.getBeanType();
Annotation[] annotations = type.getAnnotationsByType(Inject.class);
for(Annotation annotation: annotations){
Inject inject = (inject) annotation;
for(Field field :type.getDeclaredFields()){
if(field.getType().equals(inject.thisType())){
field.setAccessible(true);
field.set(handlerMethod.getBean(), Services.find(inject.thisType()));
}
}
....
return true;
}
...
}
A bean can have 4 scopes.
Singleton
Only one shared instance of the bean will be managed, and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned by the Spring container.
It is default scope of a bean.
Prototype
New instance is returned by the container when bean with the specified id is requested.
Ex: If you have a bean with id as "employee" in your spring container, then everytime you do a
Employee emp = context.getBean("employee");
A new instance will be returned.
request, session, and global session are for use only in web-based applications
Request
A new instance is created for every single HTTP request.
Ex : Login needs different instance everytime.
Session
A new instance will be created of the bean using the bean definition for the lifetime of a single HTTP Session.
global
The global session scope is similar to the standard HTTP Session scope and really only makes sense in the context of portlet-based web applications
You can specify the scope of a bean in two ways
Using XML:
<bean id="employee" class="com.company.Employee" scope="singleton"/>
Using annotation.
mark the class with #Scope("prototype")
you can read more about scopes here
sample code for reference is available here

Are autowired objects in spring-mvc threadsafe?

Question 1) From my understanding spring creates singletons objects, So when I have a controller like below with a autowired service, will that affect threadsafety.
Question 2) If I declare a int type variable at class level and use it in controller or service, will it affect thread safety?
#Controller
public class LoginController {
#Autowired
public DaoService daoservice;
#RequestMapping("/")
public String getBookInfo() {
Book book = daoservice.getBookbyId(1L);
System.out.println(book.getTitle());
return "welcome";
}
}
#Service
public class DaoService {
#Autowired
public BookRepository BookRepo;
public Book getBookbyId(Long Id) {
Book book = BookRepo.findOne(Id);
return book;
}
}
Q.1 : Are Spring Beans Thread Safe?
Answer: No.
Spring don't give you thread safety for their bean. Spring provide different type of bean scope like (Prototype,Singleton etc). If Prototype then a new bean create each time it invoke where a singleton bean created for one time and shared in application context.
If you are thinking for HTTP request, then 2 or more request can come.Hence new instance of a bean is created in each request scope. So you can think they are thread safe in context of HTTP request but it's not truly thread safe by spring itself.Because several thread can share the bean within the same HTTP request context.
Q.2 : Are Class variable Thread Safe?
Answer: No
Quoted from here
All private member variables are shared. They might be final, but that only means that the references can't be changed. Any mutable state must be synchronized.

Create a stateful session bean from a stateless bean

The context is the following :
An client application uses a stateless session bean in order to login on an EJB server application. If the login is successful, the client should get a stateful session bean in order to perform some transactions on his personal data. However, I would want that the login method returns a new instance of this stateful session bean such that a client should not be able to manually call this session bean and perform transactions without being authenticated. Is it possible ?
In my stateless bean I have the following code :
#Resource
private SessionContext context;
...
public StatefulBeanRemote login(username, password) {
if (ok) {
StatefulBeanRemote bean = (StatefulBeanRemote) context.lookup("StatefulBeanRemote");
return bean;
}
The lookup always fail. I don't know what I am doing wrong...
The lookup you're performing is the same as:
new InitialContext().lookup("java:comp/env/StatefulBeanRemote");
Have you defined an EJB reference to StatefulBeanRemote? Perhaps that is all you need:
#EJB(name="StatefulBeanRemote", beanInterface=StatefulBeanRemote.class)
public class MyClass {
#Resource
private SessionContext context;
...
}

Resources