[My Setup: Java EE 6 application, with EJB3.1, CDI/Weld, JSF2 running on Glassfish 3.0.1]
I read some articles about the new @Asynchronous methods in EJB3.1, but none of them mentioned the dangers of asynchronous methods and what you really have to care about.
In my app i’m having an @Asynchronous E-Mail service, sending lots of mails. I’m calling this Service from a CDI/Weld Bean. During my tests, i often experienced ConcurrentModificationExceptions, but until now i don’t really understand where and why it crashes sometimes.
Just to show how my Beans roughly look like, the important parts:
@Stateful @LocalBean
public class EmailEJB {
//... Injections
@Asynchronous
public Future<Integer> sendEmails(User user, Message message) {
// ... send mails
return new AsyncResult<Integer>(1);
}
}
In my CDI-Bean, i’m using this EJB like this (exposing progress to JSF2):
@Named @SessionScoped
public class MessageManager {
@EJB
public EmailEJB emailEJB;
public FutureEJB<Integer> progress;
public Integer getProgress() {
if (progress == null) return 0;
else {
return progress.get();
}
}
public String sendMessage() {
(...)
progress = emailEJB.sendEmails(user, message);
(...)
}
}
I just wanted to ask in general: am i doing something completely wrong here (Scopes, injections, using Future)? What do i have to care for when using @Asynchronous methods, to avoid ConcurrentModificationExceptions?
I’m injecting the Email as an EJB. Will it be better to make the whole EmailEJB Asynchronous and inject it with @Inject @Asynchronous? What would be the difference?
Any hints welcome!
My biggest failure was to use the Session Scope for my CDI bean. This allows only one instance of the asynchronous EJB at once – propably resulting in the ConcurrentModificationException (i think its at a point where i re-assign a Future value).
So @Asynchronous methods/classes seem to be an ideal candidate for the ConversationScope. Changed my CDI bean accordingly, no exceptions so far.