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
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 am using EJB in order to take advantages of:
Concurrent (instead of creating 2 threads, I divided the work into 2
EJB beans).
Pooling (I use stateless EJB a lot and I love the idea that the pool
contains a specific number of bean). This way, I am not afraid of
running out of memory. Memory usage is more predictable).
Asynchronous processing (all I need is just an annotation).
Well, the problem is I am using it with MongoDB so I don't need any transaction. I can use #TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) and #TransactionAttribute(TransactionAttributeType.NEVER) annotations but... it means I must specify it everywhere?
Is there anyway to disable EJB transaction by default?
In an EJB 3.0 container, annotate your EJB (or EJB method) with:
#Stateless
#TransactionManagement(TransactionManagementType.BEAN)
#TransactionAttribute(value=TransactionAttributeType.NEVER)
public class YourBean
for BEAN management. For CONTAINER management instead:
#Stateless
#TransactionManagement(TransactionManagementType.CONTAINER)
#TransactionAttribute(value=TransactionAttributeType.NEVER)
public class YourBean
The default value is managed by the container but if you dont specify nothing to do i think you solve your problem.
Or annotate all the Ejb to don´t support transaction
#Stateless
#TransactionManagement(TransactionManagementType.NEVER)
public class YourBean
Remember that the ejb transactions are executed in a hierarchical way, ie if the first method being invoked does not support methods "children methods" are handled in the same way
I have a process that I want to run serially, but in a different thread. How can I accomplish that in JBoss 7? The obvious answer would be an #Asyncronous EJB method where the EJB is configured to only have one thread running at a time (the others requests would be in queue).
How can that be best accomplished?
I believe a great way of achieving this is using a combination of Singleton + Asynchronous annotations from EJB 3.1, you can also use the AccessTimeout annotation to provide wait timeout for the queued calls and finally you can even use Lock annotation to control READ,WRITE locking on this if you want:
#Singleton
public class SingletonAsyncProcessor{
#Asynchronous
#AccessTimeout(5000) //times out after 5 seconds
public Future<String> addJobToQueue(String jobName) {
Also notice that you can use most of these annotations at class level(all methods will be async) or method level. You can even run EJB 3.1 in the web container.
EJB 3.1 ROCKS.
Regards.
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.
In EJB 3.1 I can get all timers for a specific bean using TimerService#getTimers() on the TimerService instance obtained for that bean.
What I actually need however is a system-wide version of this. I.e. I would like to have a list of all Timers in the EJB container.
Is something like that possible?
There simply is no official API for this in EJB 3.1.
If you're only using annotations and/or interfaces to mark your timeout method, you could do a run-time walk over all classes on the class path and check if this annotation or interface is present. This will at least give you the beans which theoretically can have timers associated with them.
Unfortunately, this still won't give you the actual timers for those beans. In EJB 3.1, the time information can only be requested from the session context, which as you already seem to know is private for each bean. This means that only the bean itself can see what timers it has.
As an alternative to what Nayan is suggesting, you could let your beans implement a method that gives you this info. You can then mark this method with either an interface or a custom annotation.
In your system-wide sweep over all timer classes you first try to discover all beans that can have timers associated with them, and of those you then try to find whether they have the required annotation or interface. If they don't have this latter thing, you can log a warning. The advantage of this method is that it's less likely that timers slip through the cracks.
Yet another method, but a very brittle one, is to hack into whatever private structure the container holds to store the timer information. For persistent timers there is at least the persist store which you can check, and somewhere in the container there must be the structure you're after. It must be there as the container itself has to be aware of this. Often a container has some private API to get to this and you can hack into that via reflective tricks.
It can also be that containers offer a proprietary API for this. E.g. in Java EE 5 it's impossible to do a programmatic login in the Servlet container, but JBoss AS has a proprietary API that allows you to do exactly that.
EJB 3.2 has a method called "getAllTimers()".
https://docs.oracle.com/javaee/7/api/javax/ejb/TimerService.html#getAllTimers--
Description:
Returns all active timers associated with the beans in the same module in which the caller bean is packaged. These include both the programmatically-created timers and the automatically-created timers.
Below is the sample code fragment for fetching information of all the existing timers of the system.
//---
private void viewSystemTimers(){
Collection<Timer> allTimers = sessionContext.getTimerService().getTimers();
Iterator<Timer> iterator = allTimers.iterator();
while (iterator.hasNext()) {
Timer timer = (Timer) iterator.next();
System.out.println("SYSTEM TIMER : "+timer.getInfo());
}
}
//---
You can only see timers of your own class. With the EJB Scheduler you can't list all timers of your application.
#Resource
private TimerService timerService;
for (Timer timer : timerService.getTimers()) {
// do anything
}
With Quartz you can via Scheduler.getJobNames/triggerNames for all jobs/triggers of you application.