I have a logging bean where I log how long database calls and bean method calls take via interceptors.
I have a bean that calls two #Asynchronous methods. Those two #Asynchronous methods call the database and are intercepted.
When the logging bean logs though, it appears that the database has taken 0 ms which can't be right. When I use this logging bean and all the interceptors without #Asynchronous calls everything works fine.
I'm using glassfish 3.1.2.2. The doc http://glassfish.java.net/nonav/docs/v3/api/javax/enterprise/context/RequestScoped.html says "The request context is destroyed: after the asynchronous observer notification completes," Does that mean that my logging bean instance in the #Asynchronous method is destroyed when the method completes? What can I use to accomplish my goal?
There are multiple layers:
A CDI proxy, which runs CDI interceptors and then calls the EJB.
An EJB proxy, which schedules async work and returns immediately.
EJB interceptors, which run on the async thread.
Presumably, you're using a CDI interceptor, which is measuring the time it takes for the EJB container to schedule the async work. If you switch to using an EJB interceptor instead (i.e., annotate the EJB method with #Interceptors), then you can measure the time taken to execute the work.
Related
I am too much confused the difference between #EnableAsync and AbstractDispatcherServletInitializer#isAsyncSupported().
As per this link,
The isAsyncSupported protected method of AbstractDispatcherServletInitializer provides a single place to enable async support on the DispatcherServlet and all filters mapped to it. By default this flag is set to true
Based on my knowledge #EnableAsync is to enable scan #Async annotations and provide multi-threading support. But still I am unable to understand when to use AbstractDispatcherServletInitializer#isAsyncSupported()
There is a big difference between the two, #EnableAsync with #Async are not concerned with spring-web-mvc, they allow the execution of a method asynchronously using a TaskExecutor. For example, if you had a clean up service that deletes all logs in a server, you can allow its doCleanUp method to run asynchronously without having to write the scheduling code, spring will take care of it for you:
public class CleanUpService {
#Async
public void doCleanUp() {
// This code will be executed using a different thread than the calling thread by a TaskExecuter
}
}
As you can see this is not related to web development in particular. Also note that this method returns void, but if you wanted it to return a result, for instance CleanupStatistics, you can't just write the method like this
#Async
public CleanupStatistics doCleanUp() {
// This code will be executed using a different thread than the calling thread by a TaskExecuter
return new CleanupStatistics("someinformation");
}
You are required to return either void or a Future. A Future represents the result of an asynchronous computation that you can use to obtain the result of the computation when it becomes available. We will get back to Future and see how it can be used in controller methods while isAsyncSupported is true.
isAsyncSupported is a totally different story, this flag enables Servlet 3.0 asynchronous request processing, prior to Servlet 3.0 a servlet container (Tomcat for instance) would have a thread pool that handles the processing of Http requests, each thread would handle the request till the processing is complete, even if the thread had to stay idle, for example, to wait for a database query to finish or for an API call result to come back. This affects the scalability of the servlet container. In Servlet 3.0 requests can be handled asynchronously, the container thread will call your handler method, in its turn the handler method can schedule its work to be done asynchronously and return immediately, freeing the container thread to process other requests, after the result is available any container thread can resume the processing of the request. From the prospective of the client, nothing has changed, the client, all that time, is still waiting for the result to come back, but from the perspective of the server, the container threads are better utilised.
In spring-mvc you can trigger asynchronous request processing for a controller method by returning certain java types, for example
DeferredResult
Callable
ListenableFuture
CompletionStage
CompletableFuture
Reactive types
and streaming types
If you wanted to use #Async with isAsyncSupported you could write a controller method that calls a method annotated with #Async and returns ListenableFuture.
You can learn more about task execution and scheduling here. And more about Servlet 3.0 asynch here.
If we want to experience benefits provided by Spring MVC and don't want to manually register DispatcherServlet it'll be better to use: AbstractDispatcherServletInitializer. It adds two abstract methods: createServletApplicationContext() and getServletMappings().
First method returns WebApplicationContext that will be passed to DispatcherServlet, which will be automatically added into container ServletContext. This context will be established as a child of the context returned by createRootApplicationContext() method. Second method -returns mappings that are used during servlet registration.
The #EnableAsync annotation switches on Spring’s ability to run #Async methods in a background thread pool. For Enabling asynchronous processing with Java configuration got by simply adding the #EnableAsync to a configuration class.
#EnableAsync
#Configuration
public class SpringAsyncConfigurer implements AsyncConfigurer {...}
#Async is applicable only to the public methods.
Calling the #Async method within the same class woould not work.
I have a Java EE app that's deployed on WildFly AS.
I have a method annotated with #Asynchronous and I need to set the max number of threads for this method.
I configured a new <managed-executor-service> in server config, but I don't know how to bind it to an async method.
This link: https://developer.jboss.org/message/851027#851027
provides a good answer to how (or when) to use #Asynchronous and when to use JSR-236 ExecutorService and concurrency utilities:
In short, #Asynchronous is a annotation (EE6) to mark an EJB method as async.
You can invoke the method and keep the future object to check whether the method is finished and get the result. The EJB Concurrency Utilities are provided to have a safe way in EE7 to delegate work to a parallel thread. Threads started by this ConcurrentUtilities are managed by the container.
In difference to a direct start of a Thread (which is not allowed for an EE application). There is less overhead than using #Async and you have a bit more control.
See also this link about how to inject a MES:
http://www.adam-bien.com/roller/abien/entry/injecting_an_executorservice_with_java
I have a #Stateful EJB annotated as #ConversationScoped. The client (JSF) makes a request to my EJB which: starts the conversation - conversation.begin(), do something and shows the response to the client.
The client then makes another request, the EJB does something and closes the conversation - conversation.end().
Is the #Stateful EJB removed after the conversation end? Or do I have to explicitly call #Remove?
The CDI specs say that the scoped EJBs are automatically created and destroyed when the scope is created or destroyed. The same is true for the Conversation scope. So, you should not try to call a #Remove method.
http://docs.jboss.org/cdi/spec/1.0/html/concepts.html#d0e1066
I have a process which takes a long time to compute so it's marked as #Asynchronous in a Stateless EJB. When the process finishes, I'd like it to access a SessionScoped bean from the session which started the process to store the results.
Is that possible? How?
You could #Inject the needed EJB, but that probably won't work because you have no guarantee that session will still be available when your asynchronous method invocation finishes. You're probably going to have to find another solution if you want to use asynchronous methods.
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.