Search code examples
javaservletsinitpayara

Java Servlet: Force init to create data object on Payara server start?


i'm looking for a way to generate a data object in my java servlet (on Payara) before the first request, since the created data object takes some time to parse other websites (about 4 seconds).

I assumed it is enough to set

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

in the beginning to force the initialization by the servlet container when the payara server is being started (based on http://www.codejava.net/java-ee/servlet/webservlet-annotation-examples). However, it does not work. I still have the 4 second delay for the first request, with no delay on subsequent requests. The following code works, the problem is just the delay on the first request.

@WebServlet(urlPatterns = "/reports/*", loadOnStartup = 1)
public class SingleReportServlet extends HttpServlet {

    ReportData m_myData;

    @Override
    public void init() throws ServletException {        
        m_myData = new ReportData(); //This takes about 4 seconds, once
        System.out.println("My servlet has been initialized");        
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        
        String requestPath = request.getPathInfo();
        String[] components = requestPath.split("/");
        String requestedData = components[components.length-1].trim().toUpperCase();
        String report = m_myData.getFullReport(requestedData, Locale.GERMAN, DisplayType.HTML_PARTIAL);
        String headline = "Report for "+requestedData;
        System.out.println(headline);
        System.out.println(report);         
        request.setAttribute("headline", headline);
        request.setAttribute("report", report); 
        request.getRequestDispatcher("/WEB-INF/singleReport.jsp").forward(request, response);       
    }    
}

Solution

  • Rather than having the ReportData being initialized in the servlet init method I would suggest that you utilize ServletContextListener

    e.g.

    @WebListener
    public class ServletContextListenerImpl implements ServletContextListener {
    
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            ReportData m_myData = new ReportData ();
            System.out.println("My ServletContextListenerImpl has been initialized");
    
            // then add to your session for later use
            sce.getServletContext().setAttribute("RDATA", m_myData);
        }
        ..
     }