Why do I get ClassNotFoundException when I call it from outside class?

12,260

Your error:

java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 

If it works running from Eclipse, that means you have the MySql jdbc dirver jar in the classpath of your project, but it is not available to your web application.

The project class path (build path) is not the same as the class path of your web application when deployed. Not all jars being on your project class path get exported automatically.

Usually jars in the WEB-INF/lib will be available for the web application, but jars outside of that will not.

You should either place the MySql jdbc driver jar in WEB-INF/lib, or add it to the lib folder of your Servlet container (Tomcat in your case judging by the exception stack trace).

Share:
12,260
JavaDeveloper
Author by

JavaDeveloper

Updated on June 25, 2022

Comments

  • JavaDeveloper
    JavaDeveloper almost 2 years

    Below is the code that works perfectly fine when it is executed from main (ie in eclipse RunAs java application). However if I call Statement getStatement from outside ( meaning a servlet calling it via a put ) in the same package I get java.lang.ClassNotFoundException: com.mysql.jdbc.Driver. Any pointers to why ?

    public class DBConnectivity {
    
        private static Statement getStatement(String username, String password) throws SQLException, ClassNotFoundException {
            Properties prop = new Properties();
            prop.put("user", "root");
            prop.put("password", "password");
    
            Class.forName("com.mysql.jdbc.Driver");
    
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/keeptrack", prop);
            Statement stmt = conn.createStatement();
    
            return stmt;
        }
    
        public void put(String username, String password, String table,
                String name, String exercise, String wsj, String food)
                throws SQLException, ClassNotFoundException {
            Statement stmt = getStatement(username, password);
            // checkIfTableExists(stmt, table);     
            stmt.executeUpdate(
                    "insert into " + table +
                    " " +
                    "values(\'" + name + "\', \'" +  exercise + "\', \'" + wsj + "\', \'" + food + "\')");
        }   
    
    
        public List<String> get(String username, String password, String table)
                throws SQLException, ClassNotFoundException {
            Statement stmt = getStatement(username, password);
            //checkIfTableExists(stmt, table);      
            ResultSet rs = stmt.executeQuery("select FOOD from " + table);
    
            List<String> foodData = new ArrayList<String>();
    
            while(rs.next()) {
                String output = rs.getString("FOOD");
                foodData.add(output);
            //  System.out.println("wohoo: " + output);
            }
    
            return foodData;
        }   
    
        public static void main(String[] args) throws SQLException, ClassNotFoundException {
            DBConnectivity conn = new DBConnectivity();
            conn.put("root", "password", "trackTable", "D", "B", "C", "D");
            conn.get("root", "password", "trackTable");
        }
    }
    

    Here is the servlet which calls the database:

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String username = request.getParameter("firstname");
            String password = request.getParameter("lastname");
            String firstname  = username;
            String exercise = request.getParameter("exerise");
            String wsj = request.getParameter("wsj");
            String food = request.getParameter("food");
    
    
            try {
                new DBConnectivity().put(username, password, "trackTable", firstname, exercise, wsj, food);
            } catch (ClassNotFoundException | SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    

    The new DBConnectivity().put call results in ClassNotFoundException.

    Stack trace is :

    java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1295)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1147)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:190)
    at org.ameya.dynasty.DBConnectivity.getStatement(DBConnectivity.java:27)
    at org.ameya.dynasty.DBConnectivity.get(DBConnectivity.java:63)
    at org.ameya.dynasty.ServletIndex.doGet(ServletIndex.java:39)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1513)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:744)
    
    • Elliott Frisch
      Elliott Frisch over 9 years
      I notice it's private, how do you call getStatement outside the class?
    • vefthym
      vefthym over 9 years
      private means exactly that: you cannot use it outside the class
    • JavaDeveloper
      JavaDeveloper over 9 years
      I call put, and put calls getStatement
    • Secondo
      Secondo over 9 years
      however if I call Statement getStatement from outside you said . what do you mean by that?
    • Elliott Frisch
      Elliott Frisch over 9 years
      Your code leaks Connection instances when getStatement is invoked. There are lots of good and free connection pools. I strongly urge that you use one.
    • Secondo
      Secondo over 9 years
      @javadeveloper Try to use Singleton Pattern. for you to be sure that only one instance is created.
    • janasainik
      janasainik over 9 years
      Can you post exception stack trace. You should not get 'ClassNotFoundException' unless the jar is not available.
  • JavaDeveloper
    JavaDeveloper over 9 years
    add it to the lib folder of your Servlet container -- worked :)