Reputation: 645
The title basically sums up my issue at the moment. If I have multiple instances of the Job running at/around the same time, Javamail throws an exception as it's meant to be used synchronously. Is there a way I can make it run asynchronously? Or is there an alternative to Javamail that is asynchronous?
Upvotes: 0
Views: 714
Reputation: 1701
I do this sort of thing with Quartz all the time. All you need to do is spin-off another thread. How you do that greatly depends upon your environment. Are you running on an App server or are you simply running a vanilla Java?
If the later then you simply spin-off a thread and there are numerous tutorials on that.
If you are running on an App Server like Wildfly, use the @Asynchronous tag on a Session bean. The only tricky bit is that you can't CDI into a Quartz scheduled job so you will need to use JNDI to obtain the container proxy for the session bean you desire. Something like this:
@NoArgsConstructor
@ApplicationScoped
@Slf4j
public class YourJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException
{
String message = "";
try {
final InitialContext ctx = new InitialContext();
final IYourSessionBean yoruSessionBean = (IYourSessionBean) ctx.lookup("java:global/server-core/YourSessionBean!com.somecompany.interfaces.IYourSessionBean");
final JobKey key = context.getJobDetail().getKey();
final JobDataMap dataMap = context.getJobDetail().getJobDataMap();
String taskID = dataMap.getString(BjondQuartzService.TASKID);
String descr = dataMap.getString(BjondQuartzService.DESCRIPTION);
yourSessionBean.assignTaskAsync(taskID, descr);
context.setResult("SUCCESS");
} catch(Exception e) {
log.error("Could not assign task: {}", message, e);
context.setResult("FAILURE");
}
}
}
And then on the receiving end:
@Asynchronous
@TransactionAttribute(REQUIRED)
@Override
public void assignTaskAsync(@NotNull(message="taskID must not be null")
final String taskID,
@NotNull(message="descr must not be null")
final String descr
) throws Exception {
Do some stuff here.
}
Note the @Asychronous tag. Each container has a number of threads available to it that can and will be extracted from a pool and used for asynch invocations like this. I find this easier than dealing with Runnable's directly.
Upvotes: 2
Reputation: 196
I think there are several ways to deal with such kind of tasks:
send each email in its on thread, i.e. imply separate SMTP connection;
@Async
public void sendEmail(String smtpServer, String to,String from,String subject, String body) {
send(smtpServer, to, from, subject, body);
}
Upvotes: 1