Java Automation: Schedule Email Reports with Java and Quartz

Java Automation: Schedule Email Reports with Java and Quartz

Java Automation: Schedule Email Reports with Java and Quartz

 

Automating email reports is a common requirement in many business applications—whether it’s daily sales updates, performance dashboards, or system logs. In this tutorial, we’ll explore how to build a reliable and recurring email reporting system using Java and the powerful Quartz Scheduler library. We’ll also enrich our emails with HTML content and simulate mock sales data to demonstrate a complete use case end to end.

1. Project Setup with Maven and Dependencies

To get started, we’ll use Maven to manage our project dependencies. Our solution requires three main components:

  • Quartz: For job scheduling
  • JavaMail: To send emails
  • Apache Commons Lang: For mock data generation (optional)

Add the following entries to your pom.xml file:

<dependencies>
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.3.2</version>
    </dependency>
    <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>javax.mail</artifactId>
        <version>1.6.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.12.0</version>
    </dependency>
</dependencies>

2. Define the Quartz Job to Send Emails

To send recurring emails, we define a class that implements org.quartz.Job. This class will contain all the logic to generate, format, and send the email with mock sales data:

public class EmailReportJob implements Job {

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        String reportHtml = generateMockSalesReport();
        try {
            sendEmail("sales@example.com", "Daily Sales Report", reportHtml);
        } catch (MessagingException e) {
            throw new JobExecutionException("Failed to send email", e);
        }
    }

    private String generateMockSalesReport() {
        StringBuilder sb = new StringBuilder();
        sb.append("<html><body>");
        sb.append("<h2>Daily Sales Report</h2>");
        sb.append("<table border='1' cellpadding='5'>");
        sb.append("<tr><th>Product</th><th>Units Sold</th><th>Revenue</th></tr>");
        for (int i = 1; i <= 5; i++) {
            int units = (int)(Math.random() * 100);
            double revenue = units * (10 + Math.random() * 90);
            sb.append(String.format("<tr><td>Product %d</td><td>%d</td><td>$%.2f</td></tr>", i, units, revenue));
        }
        sb.append("</table></body></html>");
        return sb.toString();
    }

    private void sendEmail(String to, String subject, String htmlContent) throws MessagingException {
        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.example.com");
        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");

        Session session = Session.getInstance(props, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("your_email@example.com", "your_password");
            }
        });

        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress("your_email@example.com"));
        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
        message.setSubject(subject);

        MimeBodyPart mimeBodyPart = new MimeBodyPart();
        mimeBodyPart.setContent(htmlContent, "text/html");

        Multipart multipart = new MimeMultipart();
        multipart.addBodyPart(mimeBodyPart);

        message.setContent(multipart);
        Transport.send(message);
    }
}

This setup uses basic JavaMail properties to send mail via TLS with authentication. You should replace SMTP details with your actual email service settings such as Gmail, Amazon SES, or a local SMTP relay.

3. Scheduling the Job with Quartz

Now that we have a Quartz job defined, we can schedule it to run, say, every day at 8 AM. We’ll configure the scheduler in our Main class:

public class SchedulerMain {
    public static void main(String[] args) throws SchedulerException {
        JobDetail job = JobBuilder.newJob(EmailReportJob.class)
                .withIdentity("emailReportJob", "group1")
                .build();

        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("dailyTrigger", "group1")
                .withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(8, 0))
                .build();

        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        scheduler.start();
        scheduler.scheduleJob(job, trigger);
    }
}

The CronScheduleBuilder is a powerful tool that lets us define precise and flexible job execution timings. In this case, our email report will be sent daily at 08:00 AM server time.

4. Practical Tips and Advanced Use Cases

Now that your job is working, consider the following enhancements:

  • Environment Configuration: Externalize SMTP credentials and cron expressions using environment variables or config files.
  • Error Handling: Track failed jobs using Quartz’s JobListener or integrate with logging/monitoring tools.
  • Dynamic Reports: Replace mock data with a real database query or REST API to pull actual metrics.
  • Thread Management: Quartz internally uses a thread pool. Configure it in quartz.properties for optimal concurrency.
  • Email Templates: Use a templating engine like Thymeleaf or FreeMarker to create more beautiful and dynamic HTML emails.

5. Conclusion

Quartz offers a robust and extensible framework for automating tasks in Java. Whether you’re generating reports, triggering data pipelines, or managing back-office automation, it’s a powerful tool in a backend engineer’s toolkit. With a bit of HTML and email integration, your scheduled jobs can not only run reliably—but also deliver high-value, nicely formatted insights to your stakeholders.

By combining Java, Quartz, and JavaMail, you’ve taken an important step toward creating self-sufficient, automated systems that scale.

 

Useful links: