1

I wanted to write async method.

@Component
public class TaskImpl implements Task{

    @Async(value="myExecutor")
    public void async(int n) throws InterruptedException{
        log.info("Executing task"+n);
        Thread.sleep(1000);
        log.info("Finished executing task" +n);

    }

}

It is nice! I have config like that:

<task:annotation-driven executor="myExecutor" />    
<task:executor id="myExecutor" pool-size="3" />

That's nice! I have write test class too!

    @Autowired
    private Task task;

    @Test
    public void mailSendTest() throws InterruptedException{
        for (int i = 0; i <5; i++) {
            task.async(i);
        }
        Thread.sleep(3000)

    }

I have tested and async works very well! tasks are in parallel!

Question 1. but when main thread of test case destroys ,Execute threads does not work. In the other words, If I do not write Thread.sleep() in test cases, Executor is shooting down immediately. How can I fix that?

2015-03-12 17:02:26.706  INFO ThreadPoolTaskExecutor: Shutting down ExecutorService

I do not want to write JOIN or Sleep.

Question 2. I need async() method in order to invoke mail sender class. In the other words I have written this component.

@Component
public class MailMail {

    private MailSender mailSender;

    public void setMailSender(MailSender mailSender) {
        this.mailSender = mailSender;
    }

    @Async
    public void sendMail(String from, String to, String subject, String msg)   {

        ....
    }


    }
}

Now I'm interested how to solve the following problem. Might be there is communication , network problem, and I can't send email. what happens now? how to catch exception and send it again?

grep
  • 5,465
  • 12
  • 60
  • 112

1 Answers1

0

For the test-case you can Mockito.spy your TaskImpl and use CountDownLetch from the doAnswer() and wait for the letch in the end of test method.

For error handling from those async task you can use ErrorHandlingTaskExecutor from Spring Integration and supply it with the ErrorHandler

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • thank you! But I have another question. In test case I can write thread.join() too, it is not problem. But in real application I should listen, when tasks will be done , after that I should destroy main thread. In the other words while(tasks are executing){ // waiting, thread is alive} – grep Mar 12 '15 at 13:32
  • `ThreadPoolTaskExecutor` has `waitForTasksToCompleteOnShutdown` and `awaitTerminationSeconds` options – Artem Bilan Mar 12 '15 at 13:34
  • thank you. But I just call interface method. I do not use ThreadPoolTaskExecutor . I have that configuration in XML. Can I retrieve ThreadPoolTaskExecutor initialized object? – grep Mar 12 '15 at 14:03
  • 1
    Instead of using that `` use `ThreadPoolTaskExecutor` directly from `` – Artem Bilan Mar 12 '15 at 15:10
  • waitForTasksToCompleteOnShutdown does not shut down java class at all. I want to shut down when everything will be finished. – grep Mar 12 '15 at 17:10
  • Not sure what you mean. You just do `applicationContext.close()` on shutdown and it will wait for those tasks. – Artem Bilan Mar 12 '15 at 17:18