Home>

Deploy and publish a web application created in Java on Tomcat.
I want to keep executing certain processing at regular intervals after releasing the web app.
When you undeploy the web application, I want to end the regular processing.
When redeploying the web application, I want to initialize the periodic process and start again.

Problems i am experiencing

-Processing does not stop when web application is undeployed from Tomcat
-When the same web application is redeployed in Tomcat, threads are duplicated.

Applicable source code

Class that performs initial processing when deploying web application

public class InitialServlet extends HttpServlet {
    // Please describe the initial processing.
    public void init () throws ServletException {
        ScheduleManager schedule = ScheduleManager.getInstance ();
        schedule.start ();
    }


Class that starts periodic processing

public class ScheduleManager extends Thread {
    private static ScheduleManager instance = new ScheduleManager ();
    private static Timer timer = new Timer ();
    private ScheduleManager () {
    }
    @Override
    public synchronized void run () {
        if (timer! = null) {
            // Stop if timer already exists
            timer.cancel ();
            System.out.println ("stop run");
        }
        // start timer
        System.out.println ("start run");
        timer = new Timer ();
        timer.schedule (Schedule.getInstance (), 0, 2000);
    }
    public static ScheduleManager getInstance () {
        return instance;
    }
}


Implementation of periodic processing

class Schedule extends TimerTask {
    private static Schedule instance = new Schedule ();
    private Schedule () {
    }
    int testCount = 0;
    @Override
    public void run () {
        System.out.println (testCount + "second");
        testCount ++;
    }
    public static Schedule getInstance () {
        return instance;
    }
}
Tried

I tried to make the ScheduleManager class and Schedule class a singleton class, but the execution result is as follows.
Every time a web application is relocated, the process is duplicated and executed periodically.
If Tomcat is restarted, it will start from "quote" once again, but Tomcat cannot be stopped in operation.

113th
63rd
91st
114th
64th
92nd
115th
65th
93rd
116th
66th
94th
Desired execution result
1st time
Second time
Third time
4th time ← If i reposition the web app here
stop run
start run
First time
Second time
Third time
4th
FW/tool version etc.

apache-tomcat-7.0.78

Supplement

I'm embarrassed, but since I'm learning by myself, I think there is an implementation that makes me laugh.
If i can point out any questions other than the main subject of this question, I would appreciate your favor.
In addition, we will add if there are any deficiencies in the question.
Thanks for your advice.


  

From the point of view, is it possible to read that while being deployed, not after deployment (during initialization) but after release (after initialization)?

You are right. Correct the question.

  

If i look further, you can read that I want to initialize the periodic process at the time of deployment. Is there any?

You are right. Correct the question.


The following listeners have been added, and they may be working fine.
If i have any other solutions or suggestions, thank you.

public class InitializationListener implements ServletContextListener {
    public void contextInitialized (ServletContextEvent event) {
    // detect startup
        System.out.println ("/////////////////////////////////////////// ////////////////////// ");
        System.out.println ("Initialized");
        System.out.println ("/////////////////////////////////////////// ////////////////////// ");
        ScheduleOutput.getInstance (). StartTimer ();
    }
    @Override
    public void contextDestroyed (ServletContextEvent event) {
    // Detect end
        System.out.println ("/////////////////////////////////////////// ////////////////////// ");
        System.out.println ("Destroyed");
        System.out.println ("/////////////////////////////////////////// ////////////////////// ");
        ScheduleOutput.getInstance (). StopTimer ();
    }
  • Answer # 1

    Hello,
    I will answer the question assuming the following.

    -I want to execute periodic processing (thread) in addition to Web applications
    -I want to start periodic processing (thread) when starting a Web application
    ・ I want to terminate the periodic processing (thread) when the Web application ends

    Maybe the answer to your question is the interface that runs when the web application starts and ends
    Because it is possible to set it as a filter, it is not recommended.

    If the above is the intention of the question, I had trouble with a similar system configuration before.
    If you start a web application, you should also start a regular execution batch thread.

    From the conclusion, start the thread when the web app starts, not the web app
    It is better to separate the process of periodic execution processing. Actually, the web application is started normally,
    Regardless of whether it is manual or not, prepare a separate batch program that starts the thread.

    It is old information, but from the viewpoint of Servlet3.0 it is possible to start a thread from a servlet.
    As a system problem, the thread always ends when the web application ends.
    Compensation is not possible. If for some reason the thread becomes zombie, the web application
    Not only will Tomcat need to be stopped. (There was no mention in the question, but in that case
    Another application running on Tomcat will also die)

    Therefore, when considering the safety of the system, the web application and thread processing are separate processes
    I think it's a good way With the above method, if the thread becomes zombie when the web application ends, the JEE container
    There is no need to terminate the main unit, and it is only necessary to terminate the batch program process.

    Slightly troublesome, start Tomcat (deploy web application), then thread processing in a separate process
    When starting and stopping, it is recognized that the web application is undeployed (stopped) and thread processing is ended.

  • Answer # 2

    Servlet init (ServletConfig config) is the default setting and will not be executed during hot deployment.

    If you want to run the init method after hot deploying your application,

    @ WebServlet (urlPatterns = "/", loadOnStartup = 1)

    It's a good idea to add a loadOnStartup attribute to the servlet and set it to something other than -1.

  • Answer # 3

    This is the class that starts regular processing

    if (timer! = null) { In this case
    private static Timer timer = new Timer ();
    Therefore, a Timer instance is always created, and this judgment will never be true.

    so
    private static Timer timer;
    And

    if (timer! = null) {
       timer.cancel ();// Stop if timer already exists
       System.out.println ("stop run");
       timer = null;
    }
    if (timer == null) {
       System.out.println ("start run");
       timer = new Timer ();// start timer
       timer.schedule (Schedule.getInstance (), 0, 2000);
    }

    I think it will work