2011-07-26 2 views
0

내가하는 일은, 서블릿 (JSP에서 호출 됨)을 실행할 때 해당 서비스의 항목을 매일 conf 파일에 넣는 것입니다 .i 스케줄러를 실행하고 싶습니다. 매일 해당 서비스에 대한 프로그램 (servlet - 실행 및 메일 보내기)을 호출하십시오. 아래 매일 스케줄을 호출하는 방법

는 내가 서버를 중지 할 때 task.but 문제가 실행하는 데 사용하는 코드입니다, 스케줄러가 중지되고 아무것도 JDK 타이머가없는 운영 체제에서, JVM에서 실행

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); 
    } 
} 
+0

스케쥴러는 JVM 내부에서 실행되기 때문에 서버를 멈 추면 바로 멈출 것이다. 어쩌면 외부 스케줄러 (자체 JVM)가 필요할까요? – home

+0

어떻게 할 수 있습니까? – sasikumar

답변

1

발생하지 . CRON 또는 Windows 스케줄러가 아닙니다. 따라서 서버 (Tomcat? JBoss? Glassfish?)를 중지하면 Timer가 살고있는 JVM을 효과적으로 중지하게되므로 더 이상 실행되지 않습니다. 서버와 독립적으로 실행되는 타이머 (스케줄러)를 원할 경우 java 명령을 사용하는 독립형 Java 프로그램 또는 다른 서버 인스턴스 내부에서 자체 JVM으로 시작해야합니다. 보조 노트에

, 당신은 몇 가지 비판, 코드의 작은 검토를 오픈 인 경우 : 가능하면 정적 및 비 정적 컨텍스트를 혼합

  • 마십시오. Schedule 클래스 인스턴스 메서드 scheduleLoad()은 상태 저장 저장소에 정적 멤버 변수를 많이 사용합니다. 변수는 메소드 실행시에만 사용되며 (이 경우 메소드 내에서 선언되어야 함) 객체의 상태를 설명하는 데 사용됩니다 (이 경우 객체의 클래스는 private 인스턴스 멤버 여야 함). 전역 상수 또는 불변의 전역 변수입니다 (이 경우 static final로 선언해야합니다). 예외가 존재하지만 덜 일반적입니다.

  • 구성원 변수 public이 (가) final이 아닌 경우 선언하지 마십시오. JavaBean 패턴을 준수하고 getters와 setter를 사용하십시오. 변수가 실제로 상수이면 public static final이어야합니다.

  • 범위를 벗어난 클래스 나 매개 변수는 사용하지 마십시오. 예를 들어 MyTimerTask은 멤버 변수 및 메서드 매개 변수로 HttpServletRequestHttpServletResponse을 사용합니다. MyTimerTask이 서블릿 요청의 범위에서 사용되지 않기 때문에 (그리고 이후에는 항상 null이 될 것입니다.) 또는 실제로 그렇다면 어떤 서블릿에서 Schedule의 정적 멤버를 명시 적으로 설정하고 scheduleLoad()을 호출하는 경우 정적 컨텍스트의 부적절한 사용에 대한 저의 첫 번째 요지를 참조하십시오. 코드가 스레드로부터 안전하지 않으며 Schedule을 사용하는 서블릿을 동시 호출해도 예기치 않은 동작이 발생합니다.

UPDATE : 그것은 내가 전문 지식의 수준이 자바로 무엇인지 잘 모르겠어요으로 시작 위치를 알고 어렵다. 독립형 Java 응용 프로그램을 실행하는 방법에 익숙하지 않은 경우 일부 자습서를 준비하는 것이 좋습니다. 오라클은 http://download.oracle.com/javase/tutorial/에 무리가 있습니다. http://download.oracle.com/javase/tutorial/getStarted/index.htmlmain 메서드를 사용하는 매우 기본적인 "hello world"유형 응용 프로그램과 java 명령을 사용하여 실행하는 방법 및 몇 가지 일반적인 실수와 문제점으로 시작하는 좋은 출발점입니다.

일단 모든 것을 알아 낸 다음에는 응용 프로그램에서 수행해야 할 작업, 필요한 리소스 및 "외부"시스템을 호출해야 할 필요가 있는지 확인하십시오. 당신은 "메일을 보내기 위해 서블릿을 실행해야한다"고 언급했다. 이는 특정 서블릿을 호출해야한다는 의미입니까, 아니면 실제로 사용자가 보낸 메일 일뿐입니다. 이 경우 어쩌면 모든 메일 전송 로직을 독립형 프로그램으로 옮길 수 있습니까?그렇지 않은 경우 브라우저와 마찬가지로 http 요청을 사용하여 서블릿을 호출해야합니다. 이와 같은 작업을 수행하기위한 여러 가지 기존 프레임 워크가 있습니다. Apache HttpClient은 매우 인기있는 것입니다.

+0

의견을 보내 주셔서 감사 드리며 위의 의견을 염두에 두십시오! "Java 명령을 사용하는 독립형 Java 프로그램 또는 다른 서버 인스턴스 내부에서 자체 JVM으로 시작해야합니다." 어떻게하면 Windows 서비스가 있다는 뜻입니까? 위의 클래스를 호출합니까? 나는 분명히 도움이되지 않습니다. – sasikumar

+0

@sasikumar : 내 업데이트를 참조하십시오. – pap

0

프로그램을 중지하면 작동하지 않습니다. 그것은 버그가 아닙니다. 그것은 기능입니다. BTW는 컴퓨터를 종료해도 아무 일도 일어나지 않습니다 :).

하지만 내 예약 된 작업을보다 강력하게 만드는 방법은 다음과 같습니다. 서버가 멈추었을 때 작업을 계속하고 다시 시작하는 방법, 예를 들어 작업 실행의 마지막 시간, 즉 스케줄러의 상태를 유지해야합니다. 특수 파일을 만들고 거기에 데이터를 저장하면됩니다. 당신은 크로스 플랫폼 순수 자바 환경 설정 API를 사용하여 이것을 할 수 있습니다 : 데이터는 유닉스의 파일 시스템과 윈도우의 레지스트리에 저장됩니다. DB에 상태를 저장할 수도 있습니다.

하지만 이미이 기능을 구현 한 다른 제품을 사용할 수 있습니다. 가장 인기 있고 유명한 Quartz입니다.

그러나 Quartz는 여전히 실행 중이며 실행중인 일부 Java 프로세스가 필요합니다. 실행중인 Java 프로세스가 없어도 작업을 실행할 수 있도록하려면 플랫폼 종속 도구 인 Windows 용 Unix 및 스케줄러 API 용 cron tab (VBScript, JScript, 명령 줄을 통해 액세스 할 수 있음)을 사용하십시오. 유닉스가있다 cron

+0

예를 들어 속성 ​​파일에서 마지막으로 실행 한 시간을 말하고 싶습니까? 위의 프로그램을 매일 오전 10시에 호출하는 cron/windows 스케줄러를 사용해야합니까? – sasikumar