In my application using Spring Batch 3.0.1 I need to get access to the thread created by SimpleAsyncTaskExecutor.createThread(Runnable runnable) before it is started in doExecute.
This needs to be done to attach security context stuff to the newly created thread.
Of course I could extend SimpleAsyncTaskExecutor and use this class, but that seems a crude solution.
I tried using Spring AOP and interceptors, but cannot intercept the right method.
Any ideas?
Edit:
protected void doExecute(Runnable task) {
Thread thread = (this.threadFactory != null ? this.threadFactory.newThread(task) : createThread(task));
thread.start();
}
I believe the correct way to handle this type of behavior would be to create your own ThreadFactory and pass that to the SimpleAsyncTaskExecutor. That would allow you access to the threads as they are being created.
You can read more about the SimpleAsyncTaskExecutor here: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/task/SimpleAsyncTaskExecutor.html
You can read more about the ThreadFactory here: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadFactory.html
Related
I am writing Spring (Java 8) web application and per each request(separate thread) my application make a few tasks, which should be completed as quickly as possible to return result to client in browser, so I'd like to find worker pool library, which can be accessed from different threads in safe way.
I have read about Execution pool, Rabbit MQ, but I couldn't find information about the feature of accessing the tasks queue from different threads.
I will really appreciate if somebody can give me advice how to do it in Java.
Here you can use asynchronous method call supported by Spring via #Async annotation.
The #Async annotated method will be executed in new thread and the result will be available in Future object (void return is also supported). Do note that the method call is non-blocking which will help return the response quickly without waiting for every task to complete. However if required the main thread can be made to wait for all task i.e. Future to complete via Future.get() which is blocking.
To configure the asynchronous support, annotate the configuration class with #EnableAsync and provide below method definition as described here.
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.initialize();
return executor;
}
I'm using the annotation based approach of spring amqp in a multithreaded environment (i have multiple consumers => multiple rabbit listener containers).
#RabbitListener(queues = "tasks")
public void receiveMessage(#Payload Task task) {
// usage of httpClient here with its own httpContext (would be fine)
// this method gets called from different listenerContainers / threads
}
My component which contains the annotated receiveMessage() method needs to do some http calls with the apache http client. Since i'm working with multiple consumers at the same time, this method gets called from different threads and the apache http client documentation says that i should create a httpContext for each thread to be thread safe. Since all threads are calling the same component method i can't put the httpContext into the component.
Is there something like a listener container context for each listener container where i can put the httpClientContext? Or does somebody have an idea how to solve this easy? I thought about ThreadLocal or a central registry for httpContexts but it would be fine if this would be more easy.
There is nothing like that provided by the framework; the simplest solution is to store them in something like a LinkedBlockingQueue and check one out, use it, and put it back in the queue when you're done (creating one as necessary if the queue is empty).
ThreadLocal will work too, but I prefer to use a pool.
I created a public method with #Async and I also have a bean for that class in which this method is created. But when I am calling it , it is not behaving async and getting blocked. Then I created a executor in application-bean and used #Async(value = “executorname”), even this is not working and on every call I am getting “beanFactory must be set on AnnotationasyncExecutionAspect to access qualified executor”.
in my application bean.xml I have
there are then few executors and schedulers and I want to use one new executor.
Please tell me how to get away with this error and get async behaviour
Thanks in advance
I was experiencing exactly the same issue and find out a solution I hope works for you (https://jira.spring.io/browse/SPR-10276).
Apparently if you unabled Spring's AspectJ aspects into your project (by using aspectj-maven-plugin, for instance), Spring's Async mechanism can be placed twice in your bean, one by aspectj and other by proxy. But, since it doesn't know it, AnnotationAsyncExecutionAspect will not be injected with a BeanFactory and you will see the assertion exception you had.
To fix it, you must instruct Spring's Async mechanism to use the AspectJ support. Do this incluing this in your Application Context.
<task:annotation-driven mode="aspectj"/>
I hope I could be of any help.
For annotation based configuration you can use #EnableAsync(mode = AdviceMode.ASPECTJ)
We are using declarative spring transaction attribute for database integrity. Some of our code call webservice which do bunch of stuffs in sharepoint. The problem is when webservices take longer time users get deadlock from spring which is holding up backend.
If I make a new thread inside a function which has spring transaction declarative attribute will that be ignored from spring?
[Transaction(TransactionPropagation.Required, ReadOnly = false)]
public void UploadPDFManual(/*parameters*/)
{
//DO some data base related things
if (revisionPDFBytes != null)
{
//my sharepoint call which calls webservice
Task.Factory.StartNew(() => DocumentRepositoryUtil.CreateSharepointDocument(docInfo)); // I draw a new thread from ASPNET worker thread pool.
}
}
Anything other options I should go for?
You don't need doing it in a transaction. Transaction makes a database save an object properly. That's it. All other stuff must be done after the transaction commit. In Java, you can make it with Spring's transaction synchronization or JMS. Take a look at the accepted answer over here.
More useful info specific for .NET (see 17.8).
I am working on a standalone application using Spring/JPA and I am trying to release properly the database resources used.
In a Web application using tomcat for example, we shutdown the server, and this way, we let Tomcat manage the resources.
But as I am in a standalone app, I have to take care about this, I use Runtime.getRuntime().addShutdownHook to "catch" the shutdown event and call ((ClassPathXmlApplicationContext) context).close();, something like this:
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
((ClassPathXmlApplicationContext) context).close();
}
It works but with an exception in the stacktrace if a thread was using a connection.
I am wondering if there is another option? Maybe getting a list of open transactions and force them to rollback?
I believe that you would need to implement something like this and inside your destroy method, you would retrieve your datasource and call a close method or something similar. I'm also assuming you have a few things to do when you shutdown your application.
I can't quite help with the right method name as I don't know what you are using for your datasource.