0

I have a Java application running on Tomcat 9. One of the dependecies of this project is mysql-connector-java-5.1.18-bin (declared on pom.xml), as the program accesses a MySQL database on certain conditions.

There's no problem when the database is accessed on doGet method (that is, on a request).

Upon development, however, I had to create a job that runs every 30 minutes and is started on server start. This method accesses the database.

The method is called and fixed to run every 30 minutes the following way (as showed on this question):

public void contextInitialized(ServletContextEvent arg0) {
    // Tasks done on server start

    Timer t = new Timer();
    MyTask mTask = new MyTask();
    // Runs every 30 minutes
    t.scheduleAtFixedRate(mTask, 0, 1800000);
}

And declared on web.xml as follows:

<listener>
    <listener-class>
        timed.MyServletContextListener
    </listener-class>
</listener>

However, upon start and on following loops, I get this exception:

java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/iot

HOWEVER, after the first request is made to the servlet (via a doGet()), this error disappears, and the job manages to run properly.

It seems that the servlet can't find the dependencies until a request is made. Is there a way do go around this? Or do I have to make a request first?

EDIT

Here's the web.xml file:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">  
<display-name>IOTServer</display-name>   
<context-param>
    <param-name>AppID</param-name>
    <param-value>123</param-value>   
</context-param>   
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>           
      /WEB-INF/applicationContext.xml
    </param-value>   
</context-param>   
<welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>default.html</welcome-file> 
</welcome-file-list>   
<listener>
    <listener-class>
        timed.MyServletContextListener
    </listener-class> 
</listener> 
</web-app>

And here's the servlet class:

@WebServlet(value="/iotIN", loadOnStartup=1)
public class IoTIN extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // make the necessary operations
    }
Ernani
  • 319
  • 1
  • 4
  • 18

2 Answers2

0

contextInitialized All ServletContextListeners are notified of context initialization before any filters or servlets in the web application are initialized. check the initialization of your database connection pool, try initializing it from your listener class directly. Alternatively, you can move this scheduler task invocation to init () method of any servlet and don't forget to remove lazy loading of that servlet.

0

After some more changes and new functionalities, I've managed to stumble on an answer. From what I can tell, the driver needs to be explicitly declared in the getGonnection() function.

Based on this answer, here's the code:

public static Connection getConnection() {
    String driver = "com.mysql.jdbc.Driver";
    String DB_username = "root";
    String DB_password = "pass";
    String DB_URL = "jdbc:mysql://localhost:3306/DATABASE";
    try {
        Class.forName(driver);
        java.sql.Connection con = DriverManager.getConnection(DB_URL, DB_username, DB_password);
        return con;

    } catch (ClassNotFoundException | SQLException e) {
        System.out.println("Exception " + e);
        return null;
    }
}

It seems the gist is in the Class.forName() line. There's some more info about it here.

In case anyone wants to know, here's the previous getConnection() function (that wasn't working):

public static Connection getConnection() throws SQLException {
    Connection conn = null;
    Properties connectionProps = new Properties();
    connectionProps.put("user", "root");
    connectionProps.put("password", "root");

    conn = DriverManager.getConnection(
               "jdbc:mysql://localhost:3306/DATABASE",
               connectionProps);

    return conn;
}
Ernani
  • 319
  • 1
  • 4
  • 18