如何每天调用调度程序

时间:2011-07-26 06:14:42

标签: java scheduling scheduler

我所做的是,当我第一次运行一个servlet(从jsp调用)时,在放入该服务的一个条目时,每天在conf file.i中运行一个调用程序,它将调用程序(servlet-每天为该服务运行并发送邮件10。

下面是我用来执行任务的代码。但问题是当我停止服务器时,调度程序停止并且没有任何反应

public class Schedule
{
    public static final String CONF_PATH = "../webapps/selen/WEB-INF/scheduling.properties";
    public static Properties schProps = null;
    public static FileInputStream sis = null;
    public static long period;
    public static Timer timer = new Timer();
    public static String servicename = null;
    public static String keyValues = null;
    public static String reValues[] = null;
    public static String schedulingValue = null;
    public static String service_url = null;
        public static String browserlist = null;
        public static String testType = null;
    public static String mailCheacked = null;
        public static String toaddr = null;
    public static HttpServletRequest request = null;
    public static HttpServletResponse response = null;
    public static String serversURL = null;
    public static String contextPath = null;
        public static Date delay = null;
    public void scheduleLoad(String serviceValue) throws Exception
    {
        try
            {
            schProps = new Properties();
            sis = new FileInputStream(CONF_PATH);
            schProps.load(sis);
            servicename = SServlet.serviceName; 
            keyValues = schProps.getProperty(serviceValue);
            reValues = keyValues.split(",");
            String request = reValues[0];
            String response = reValues[1];
            schedulingValue = reValues[2];
            service_url = reValues[3];
            browserlist = reValues[4];
            testType = reValues[5];
            mailCheacked = reValues[6];
            toaddr = reValues[7];
            serversURL = reValues[8];
            contextPath = reValues[9];
            if(reValues[2].equals("Daily"))
            {

                Calendar cal =Calendar.getInstance();
                cal.set(Calendar.HOUR,10);
                cal.set(Calendar.MINUTE,20);
                cal.set(Calendar.SECOND,0);
                delay = cal.getTime();
                period = 1000 * 60 * 60 * 24;
                schedule();
            }
            else if(reValues[2].equals("Stop"))
            {
                stop();
            }   
        }
        catch(NullPointerException npe)
        {
            System.out.println("null point exception ");
        }
        finally
        {
            if(sis !=null)
            {
                sis.close();
            }
        }           

    }
    public static void schedule()
    {
        MyTimerTask mt = new MyTimerTask(request,response,servicename,service_url,browserlist,mailCheacked,testType,schedulingValue,toaddr,serversURL,contextPath);
        timer.schedule(mt,delay,period);
    }
    public static void stop()
    {
        timer.cancel();
    }

} 
class MyTimerTask extends TimerTask
{
    public HttpServletRequest request;
    public HttpServletResponse response;    
    public String servicename;
    public String service_url;
    public String browserlist;
    public String mailCheacked;
    public String testType;
    public String schedulingValue;
    public String toaddr;
    public String serversURL;
    public String contextPath;
    public MyTimerTask(HttpServletRequest request,HttpServletResponse response, String servicename,String service_url,String browserlist,String mailCheacked,String testType,String schedulingValue,String toaddr,String serversURL, String contextPath)
    {
        this.request = request;
        this.response = response;
        this.servicename = servicename;
        this.service_url = service_url;
        this.browserlist = browserlist;
        this.mailCheacked = mailCheacked;
        this.testType = testType;
        this.schedulingValue = schedulingValue;
        this.toaddr = toaddr;
        this.serversURL = serversURL;
        this.contextPath = contextPath;
    }
    public void run()
    {
        SServlet sservlet = new SServlet();
        sservlet.sServerloading(request,response,servicename,service_url,browserlist,mailCheacked,testType,schedulingValue,toaddr,false,1,serversURL,contextPath);
    }
}

2 个答案:

答案 0 :(得分:1)

JDK Timer在JVM中运行,而不是在操作系统中运行。它不是CRON或Windows调度程序。所以,当你停止服务器(Tomcat?JBoss?Glassfish?)时,你有效地停止了Timer所在的JVM,当然它不会再运行了。如果您想要一个独立于服务器运行的计时器(调度程序),则必须在它自己的JVM中启动它,或者使用java命令作为独立的Java程序,或者在另一个服务器实例中启动它。

在旁注中,如果您对某些批评持开放态度,请对您的代码进行一些小评论:

  • 尽可能避免混合静态和非静态上下文。您的Schedule类实例方法scheduleLoad()大量使用静态成员变量进行有状态存储。变量要么仅用于执行方法(在这种情况下它们应该在该方法中声明),要么它们用于描述对象的状态(在这种情况下它们应该是类的私有实例成员)或者它们是全局常量或不可变全局变量(在这种情况下,它们应声明为static final)。这些例外情况存在,但不太常见。

  • 如果成员变量public不同,则避免声明成员变量final。坚持JavaBean模式,使用getter和setter。如果变量实际上是一个常数,那么它应该是public static final

  • 避免使用超出范围的类或参数。例如,您的MyTimerTask使用HttpServletRequestHttpServletResponse作为成员变量和方法参数。这没有任何意义,因为MyTimerTask未在servlet请求的范围内使用(并且随后将始终为null,对吧?)。或者,如果确实如此,如果您在某个servlet中显式设置Schedule的静态成员然后调用scheduleLoad(),请参阅我关于不正确使用静态上下文的第一点。您的代码不是线程安全的,并且使用Schedule的任何servlet的并发调用都会产生不可预测的行为。

更新: 我很难知道从哪里开始,因为我不确定你在Java中的专业水平。如果您不熟悉如何执行独立的Java应用程序,我建议您参加一些教程。 Oracle在http://download.oracle.com/javase/tutorial/有一堆。 http://download.oracle.com/javase/tutorial/getStarted/index.html是一个很好的起点,因为它引导您使用main方法完成一个非常基本的“hello world”类型应用程序,以及如何使用java命令执行它,以及一些常见的错误和问题。

一旦你想出了这一切,花几分钟时间弄清楚你的应用程序应该做什么,它需要哪些资源以及是否需要调用任何“外部”系统。你提到它应该“执行一个servlet来发送邮件”。这是否意味着它必须调用特定的servlet,或者它只是发送邮件,而这正是你所追求的。在这种情况下,也许您可​​以将所有邮件发送逻辑移动到您的独立程序?如果没有,您将不得不使用http请求调用servlet(就像浏览器一样)。有许多现有的框架可以做这样的事情。 Apache HttpClient非常受欢迎。

答案 1 :(得分:0)

如果停止程序,它将无效。这不是一个bug。这是一个功能。顺便说一下,如果关闭计算机,也没有任何事情发生:)。

但是,如果你的任务是如何使我的计划任务更加健壮,例如如何使任务在服务器停止然后再次启动时继续工作,你必须在调度程序的某个状态,即在你的情况下最后一次执行任务。您可以自己实现:创建特殊文件并将数据存储在那里。您可以使用跨平台纯Java Preferences API来执行此操作:数据将存储在Unix中的文件系统和Windows中的Registry中。你也可以在DB中保存状态。

但您可以使用已实现此功能的其他产品。最受欢迎和最着名的是Quartz。

但是Quartz仍然需要一些java进程才能启动并运行。如果您希望能够运行您的任务,即使没有运行任何Java进程,也可以使用平台相关工具:用于Unix的cron tab和用于Windows的调度程序API(可通过VBScript,JScript,命令行访问)。 Unix有cron