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");
}

}

Sending Email with Attachments using JavaMail

We can send emails using JavaMail API.
Instead of directly using JavaMail API here is a small utility to send emails which shields the user from JavaMail internals.

EmailConfiguration.java

package com.sivalabs.email;
import java.util.Properties;

public class EmailConfiguration
{
private Properties properties = new Properties();

public static final String SMTP_HOST = "mail.smtp.host";
public static final String SMTP_AUTH = "mail.smtp.auth";
public static final String SMTP_TLS_ENABLE = "mail.smtp.starttls.enable";
public static final String SMTP_AUTH_USER = "smtp.auth.user";
public static final String SMTP_AUTH_PWD = "smtp.auth.pwd";
public static final String DEBUG = "debug";

public Properties getProperties()
{
return this.properties;
}

public void setProperty(String key, String value)
{
this.properties.put(key, value);
}

public void addProperties(Properties props)
{
this.properties.putAll(props);
}

public String getProperty(String key)
{
return this.properties.getProperty(key);
}
}

Email.java

package com.sivalabs.email;
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.email;

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

public Attachment()
{
}

public Attachment(byte[] data, String filename, String mimeType)
{
super();
this.data = data;
this.filename = filename;
this.mimeType = mimeType;
}

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;
}

}

EmailService.java

package com.sivalabs.email;

import java.util.List;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;

public class EmailService
{
private EmailConfiguration configuration = null;
private Authenticator auth =null;

public EmailService(EmailConfiguration configuration)
{
this.configuration = configuration;
this.auth = this.buildSmtpAuthenticator();
}

private Authenticator buildSmtpAuthenticator()
{
String emailId = configuration.getProperty(EmailConfiguration.SMTP_AUTH_USER);
String password = configuration.getProperty(EmailConfiguration.SMTP_AUTH_PWD);
return new SMTPAuthenticator(emailId, password);
}

public void sendEmail(Email email)
{
Session session = Session.getDefaultInstance(this.configuration.getProperties(), auth);
boolean debug = Boolean.valueOf(this.configuration.getProperty(EmailConfiguration.DEBUG));
session.setDebug(debug);

try
{
Message msg = this.buildEmailMessage(session, email);
Transport.send(msg);
}
catch (MessagingException e)
{
throw new RuntimeException(e);
}
}

private Message buildEmailMessage(Session session, Email email) throws MessagingException
{
Message msg = new MimeMessage(session);
msg.setSubject(email.getSubject());
this.addRecievers(msg, email);
Multipart multipart = new MimeMultipart();
this.addMessageBodyPart(multipart, email);
this.addAttachments(multipart, email);
msg.setContent(multipart);
return msg;
}

private void addRecievers(Message msg, Email email) throws MessagingException
{
InternetAddress from = new InternetAddress(email.getFrom());
msg.setFrom(from);

InternetAddress[] to = this.getInternetAddresses(email.getTo());
msg.setRecipients(Message.RecipientType.TO, to);

InternetAddress[] cc = this.getInternetAddresses(email.getCc());
msg.setRecipients(Message.RecipientType.CC, cc);

InternetAddress[] bcc = this.getInternetAddresses(email.getBcc());
msg.setRecipients(Message.RecipientType.BCC, bcc);

}
private void addMessageBodyPart(Multipart multipart, Email email) throws MessagingException
{
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(email.getText(), email.getMimeType());
multipart.addBodyPart(messageBodyPart);
}
private void addAttachments(Multipart multipart, Email email) throws MessagingException
{
List<Attachment> attachments = email.getAttachments();
if(attachments != null && attachments.size() > 0)
{
for (Attachment attachment : attachments)
{
BodyPart attachmentBodyPart = new MimeBodyPart();
String filename = attachment.getFilename() ;
DataSource source = new ByteArrayDataSource(attachment.getData(),
attachment.getMimeType());
attachmentBodyPart.setDataHandler(new DataHandler(source));
attachmentBodyPart.setFileName(filename);
multipart.addBodyPart(attachmentBodyPart);
}
}
}
private InternetAddress[] getInternetAddresses(String... addresses)
throws AddressException
{
if(addresses == null || addresses.length == 0)
{
return null;
}
InternetAddress[] iAddresses = new InternetAddress[addresses.length];
for (int i = 0; i < addresses.length; i++)
{
iAddresses[i] = new InternetAddress(addresses[i]);
}
return iAddresses;
}
}

class SMTPAuthenticator extends javax.mail.Authenticator
{
private String username;
private String password;

public SMTPAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}

public PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(username, password);
}
}

Add the mail.jar, activation.jar to the classpath. Here is the TestClient on how to use the EmailService Utility.

package com.sivalabs.email;

public class EmailClient
{
public static void main(String[] args)
{
EmailConfiguration configuration = new EmailConfiguration();
configuration.setProperty(EmailConfiguration.SMTP_HOST, "smtp.gmail.com");
configuration.setProperty(EmailConfiguration.SMTP_AUTH, "true");
configuration.setProperty(EmailConfiguration.SMTP_TLS_ENABLE, "true");
configuration.setProperty(EmailConfiguration.SMTP_AUTH_USER, "xyz@gmail.com");
configuration.setProperty(EmailConfiguration.SMTP_AUTH_PWD, "**********");

EmailService emailService = new EmailService(configuration);
Email email = new Email();
email.setFrom("sivaprasadreddy.k@gmail.com");
email.setTo("sivaprasadreddy_k@yahoo.co.in");
email.setCc("sivaprasadreddy.k@gmail.com");

email.setSubject("Test Mail from SivaLabs");
email.setText("Hi,

This is a test email from Siva Labs

");
email.setMimeType("text/html");

Attachment attachment1 = new Attachment("ABCDEFGH".getBytes(), "test1.txt","text/plain");
email.addAttachment(attachment1);

Attachment attachment2 = new Attachment("XYZZZZZZ".getBytes(), "test2.txt","text/plain");
email.addAttachment(attachment2);

emailService.sendEmail(email);

}

}