Search code examples
javajakarta-eeejbschedule

Java EJB @Schedule annotation method is being called twice


I am working on a J2EE project that, in short, sends an automated email to a user at a designated time, and allows the user to download files from the webpage that is emailed to them. It works pretty well.

However, my timer method that uses the @Schedule annotation is invoked twice. The method always executes immediately at run time (which I don't want), then later at the designated time. I have included code for the Servlet that is loaded when my application is deployed, the Schedule class, and my web.xml file.

DeployApplicationServlet class:

package downloadsupport;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import scheduleTimer.ScheduleEmail;

/**
 * Servlet implementation class InitializeApplicationServlet
 */
@WebServlet("/DeployApplicationServlet")
public class DeployApplicationServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public DeployApplicationServlet() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        PrintWriter out = response.getWriter();
        out.println("Web Application Started");

        ScheduleEmail se = new ScheduleEmail();
        se.sendAutomatedEmail();
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {

    }
}

ScheduleEmail class:

package scheduleTimer;

import java.util.Date;

import javax.ejb.Schedule;
import javax.ejb.Stateless;

import java.net.*;
import java.io.*;


@Stateless
public class ScheduleEmail {

    @Schedule(second = "0", minute = "10", hour = "12", dayOfWeek = "Wed")
    public void sendAutomatedEmail() {
        // Print Time to console for testing purposes
        System.out.println(new Date());

        // Invoke the SendEmailServlet at the designated time
        try {
            URL emailServlet = new
                URL("http://localhost:9081/downloadsupport/SendEmailServlet");
            URLConnection servletConn = emailServlet.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(
                        servletConn.getInputStream()));
            String inputLine;

            while ((inputLine = in.readLine()) != null)
                System.out.println(inputLine);
            in.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

web.xml config:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name>downloadsupport</display-name>

    <servlet>
        <servlet-name>SendEmailServlet</servlet-name>
        <servlet-class>downloadsupport.SendEmailServlet</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>DeployApplicationServlet</servlet-name>
        <servlet-class>downloadsupport.DeployApplicationServlet</servlet-class>
    </servlet>

    <welcome-file-list>
        <welcome-file>DeployApplicationServlet</welcome-file>
        <!--  <welcome-file>SendEmailServlet</welcome-file> -->
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>DownloadServet</servlet-name>
        <servlet-class>downloadsupport.DownloadServlet</servlet-class>
    </servlet>

    <!--
 <servlet-mapping>
    <servlet-name>DownloadServlet</servlet-name>
    <url-pattern>/downloadServlet</url-pattern>
</servlet-mapping>
 -->
</web-app>

Solution

  • Your first, unwanted call is caused by you, not by not working server.

    You dont need to instantiate ScheduleEmail. Remove these two lines form the servlet and it will work ok.

    Container is responsible for initializing your bean and calling methods marked with @Schedule