Spring + Quartz + JavaMail Integration Tutorial

Quartz is a job scheduling framework which is used to schedule the jobs to be executed on the specified time schedule.
JavaMail is an API to send/recieve emails from Java Applications.

Spring has integration points to integrate Quartz and JavaMail which makes easy to use those APIs.

Lets create a small demo application to show how to integrate Spring + Quartz + JavaMail.

Our application is to send birthday wishes emails to friends everyday at 6 AM.

Email.java

package com.sivalabs.reminders;

import java.util.ArrayList;
import java.util.List;

public class Email
{
private String from;
private String[] to;
private String[] cc;
private String[] bcc;
private String subject;
private String text;
private String mimeType;
private List<Attachment> attachments = new ArrayList<Attachment>();

public String getFrom()
{
return from;
}
public void setFrom(String from)
{
this.from = from;
}
public String[] getTo()
{
return to;
}
public void setTo(String... to)
{
this.to = to;
}
public String[] getCc()
{
return cc;
}
public void setCc(String... cc)
{
this.cc = cc;
}
public String[] getBcc()
{
return bcc;
}
public void setBcc(String... bcc)
{
this.bcc = bcc;
}
public String getSubject()
{
return subject;
}
public void setSubject(String subject)
{
this.subject = subject;
}
public String getText()
{
return text;
}
public void setText(String text)
{
this.text = text;
}
public String getMimeType()
{
return mimeType;
}
public void setMimeType(String mimeType)
{
this.mimeType = mimeType;
}
public List<Attachment> getAttachments()
{
return attachments;
}
public void addAttachments(List<Attachment> attachments)
{
this.attachments.addAll(attachments);
}
public void addAttachment(Attachment attachment)
{
this.attachments.add(attachment);
}
public void removeAttachment(int index)
{
this.attachments.remove(index);
}
public void removeAllAttachments()
{
this.attachments.clear();
}
}

Attachment.java

package com.sivalabs.reminders;

public class Attachment
{
private byte[] data;
private String filename;
private String mimeType;
private boolean inline;

public Attachment()
{
}

public Attachment(byte[] data, String filename, String mimeType)
{
this.data = data;
this.filename = filename;
this.mimeType = mimeType;
}
public Attachment(byte[] data, String filename, String mimeType, boolean inline)
{
this.data = data;
this.filename = filename;
this.mimeType = mimeType;
this.inline = inline;
}
public byte[] getData()
{
return data;
}
public void setData(byte[] data)
{
this.data = data;
}
public String getFilename()
{
return filename;
}
public void setFilename(String filename)
{
this.filename = filename;
}

public String getMimeType()
{
return mimeType;
}

public void setMimeType(String mimeType)
{
this.mimeType = mimeType;
}

public boolean isInline()
{
return inline;
}

public void setInline(boolean inline)
{
this.inline = inline;
}

}

EmailService.java

package com.sivalabs.reminders;

import java.util.List;

import javax.activation.DataSource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.mail.util.ByteArrayDataSource;

import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;

public class EmailService
{
private JavaMailSenderImpl mailSender = null;
public void setMailSender(JavaMailSenderImpl mailSender)
{
this.mailSender = mailSender;
}

public void sendEmail(Email email) throws MessagingException {
MimeMessage mimeMessage = mailSender.createMimeMessage();
// use the true flag to indicate you need a multipart message
boolean hasAttachments = (email.getAttachments()!=null &&
email.getAttachments().size() > 0 );
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, hasAttachments);
helper.setTo(email.getTo());
helper.setFrom(email.getFrom());
helper.setSubject(email.getSubject());
helper.setText(email.getText(), true);

List<Attachment> attachments = email.getAttachments();
if(attachments != null && attachments.size() > 0)
{
for (Attachment attachment : attachments)
{
String filename = attachment.getFilename() ;
DataSource dataSource = new ByteArrayDataSource(attachment.getData(),
attachment.getMimeType());
if(attachment.isInline())
{
helper.addInline(filename, dataSource);
}else{
helper.addAttachment(filename, dataSource);
}
}
}

mailSender.send(mimeMessage);
}
}

BirthdayWisherJob.java

package com.sivalabs.reminders;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.mail.MessagingException;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class BirthdayWisherJob extends QuartzJobBean
{

private EmailService emailService;
public void setEmailService(EmailService emailService)
{
this.emailService = emailService;
}

@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException
{
System.out.println("Sending Birthday Wishes... ");
List<User> usersBornToday = getUsersBornToday();
for (User user : usersBornToday)
{
try
{
Email email = new Email();
email.setFrom("admin@sivalabs.com");
email.setSubject("Happy BirthDay");
email.setTo(user.getEmail());
email.setText("

Dear "+user.getName()+
",
Many Many Happy Returns of the day :-)

");

byte[] data = null;
ClassPathResource img = new ClassPathResource("HBD.gif");
InputStream inputStream = img.getInputStream();
data = new byte[inputStream.available()];
while((inputStream.read(data)!=-1));

Attachment attachment = new Attachment(data, "HappyBirthDay",
"image/gif", true);
email.addAttachment(attachment);

emailService.sendEmail(email);
}
catch (MessagingException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

private List<User> getUsersBornToday()
{
List<User> users = new ArrayList<User>();
User user1 = new User("Siva Prasad", "sivaprasadreddy.k@gmail.com", new Date());
users.add(user1);
User user2 = new User("John", "abcd@gmail.com", new Date());
users.add(user2);
return users;
}
}

applicationContext.xml






<ref bean="birthdayWisherCronTrigger" />




<property name="jobDetail" ref="birthdayWisherJob" />
<!-- run every morning at 6 AM -->
<property name="cronExpression" value="0/5 * * * * ?" />



<property name="jobClass" value="com.sivalabs.reminders.BirthdayWisherJob" />












<property name="defaultEncoding" value="UTF-8"/>
<property name="host" value="smtp.gmail.com" />
<property name="port" value="465" />
<property name="protocol" value="smtps" />
<property name="username" value="admin@gmail.com"/>
<property name="password" value="*****"/>


true
true
true





TestClient.java

package com.sivalabs.reminders;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestClient {


public static void main(String[] args)
{
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
}

}

10 thoughts on “Spring + Quartz + JavaMail Integration Tutorial

  1. Thank you for a very informative post! I could not find much documentation on integrating Spring and Quartz, other than the Spring manual wich is quite limiting.

    One question: you define the CronTrigger expression in the Spring's config file:

    Do you know if it is possible to overwrite this property dynamically, at run time, from my application – if, for example, I want to let users specify how often they want to get mail notifications?

    thanks!
    Marina

  2. Hi,
    Recently I am also tried to do the same thing.
    Spring framework wrapper classes around core Quartz classes are setting the required parameters in the init callback methods. I tried to hack them and place the dynamic values for cron expression, but it is becoming too messy.

    Instead of the I would suggest to directly use Quartz and manage the jobs using core quartz classes.

    Thanks,
    Siva

Leave a Reply

Your email address will not be published. Required fields are marked *