Tomcat 6.0 с JDBC создает исключение ClassNotFoundException com.mysql.jdbc.Connection - PullRequest
2 голосов
/ 31 августа 2010

Я успешно подключился к базе данных MySQL через Eclipse, не вовлекая tomcat, так что в аренду это хороший прогресс. Но когда я пытаюсь с моей веб-страницы (Tomcat 6.0), он выдает ошибку. Я следовал учебным пособиям, читал документацию и просматривал бесчисленные форумы, но не могу разобраться в течение 2 дней.

Давайте посмотрим на шаг один за другим. Я использую tomcat 6.0.26 и у меня установлен и работает MySQL.

1. Поместите разъем j в CATALINA_HOME/lib

makun /home/makun/tomcat/apache-tomcat-6.0.26/lib ->ls | grep -i mysql*
mysql-connector-java-5.1.13-bin.jar

2. Расскажите Tomcat о моей информации MySQL. (объявить требования к ресурсам), а также отобразить сервлет, используемый для вызова теста db (т.е. / tmp_db_test)

(/ WEB-INF / web.xml)

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

    <servlet>
        <servlet-name>DatabaseTest</servlet-name>
        <servlet-class>com.masatosan.tmp.Tmp</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>DatabaseTest</servlet-name>
        <url-pattern>/tmp_db_test</url-pattern>
    </servlet-mapping>

    <resource-ref>
      <description>DB Connection</description>
      <res-ref-name>jdbc/MasatoDB</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
    </resource-ref>


</web-app>

3. Настройте фабрику ресурсов Tomcat.

(CATALINE_HOME / CONF / context.xml)

<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>

<!-- Masato added the line below to setup JDBC -->
<Resource 
    name="jdbc/MasatoDB" 
    auth="Container" 
    type="javax.sql.DataSource"
    maxActive="100" 
    maxIdle="30" 
    maxWait="10000"
    username="masato" 
    password="mypass" 
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/masatosan"/>

4. создать страницу JSP, которая вызывает сервлет
Это просто страница с одной кнопкой, которая отправляет запрос POST.

 <html>
    <head>
    </head>
    <body>
    <!-- click button to send request to servlet -->
    <form method="POST" action="tmp_db_test">
    <p><input type="submit" value="Submit" name="submit_button"></p>
    </form>
    </body>
    </html> 

5. Наконец, реализуйте сервлет, который пытается подключиться к базе данных MySQL.
(Tmp.java)

package com.masatosan.tmp;

import java.io.IOException;
//import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import com.masatosan.dateformatter.DateFormatter;
import com.masatosan.logger.Logger;
import com.mysql.jdbc.Connection;


public class Tmp extends HttpServlet {


    private Connection conn;

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            Context initCtx = new InitialContext();
            Context envCtx = (Context) initCtx.lookup("java:comp/env");
            DataSource ds = (DataSource)envCtx.lookup("jdbc/MasatoDB");

            conn = (Connection) ds.getConnection();

            String template = "INSERT INTO users(username, email, password, created_date) VALUES (?, ?, ?, ?);";
            PreparedStatement inserter = conn.prepareStatement(template);
            inserter.setString(1, "test_username");
            inserter.setString(2, "test@test.com");
            inserter.setString(3, "test_pass");
            inserter.setString(4, DateFormatter.formatToSqlDate(null));

            inserter.executeUpdate();
        }
        catch(Exception e) {
            Logger.log(e.getMessage());
        }
        finally {
            if(conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    Logger.log(e.getMessage());
                }
            }
        }
    }
}

Я выполнил Tmp.java и вставил в /WEB-INF/classes/com/masatosan/tmp/Tmp.class

Затем повторно развернул сервер Tomcat и протестировал его в браузере. Когда я нажимаю кнопку отправки, я получаю сообщение об ошибке:

javax.servlet.ServletException: Error instantiating servlet class com.masatosan.tmp.Tmp
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    java.lang.Thread.run(Thread.java:619)

root cause

java.lang.NoClassDefFoundError: Lcom/mysql/jdbc/Connection;
    java.lang.Class.getDeclaredFields0(Native Method)
    java.lang.Class.privateGetDeclaredFields(Class.java:2291)
    java.lang.Class.getDeclaredFields(Class.java:1743)
    org.apache.catalina.util.DefaultAnnotationProcessor.processAnnotations(DefaultAnnotationProcessor.java:181)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    java.lang.Thread.run(Thread.java:619)

root cause

java.lang.ClassNotFoundException: com.mysql.jdbc.Connection
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1516)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1361)
    java.lang.Class.getDeclaredFields0(Native Method)
    java.lang.Class.privateGetDeclaredFields(Class.java:2291)
    java.lang.Class.getDeclaredFields(Class.java:1743)
    org.apache.catalina.util.DefaultAnnotationProcessor.processAnnotations(DefaultAnnotationProcessor.java:181)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    java.lang.Thread.run(Thread.java:619)

Пожалуйста, дайте мне знать, если вам нужно больше разъяснений.

EDIT

Согласно предложению jar Connectorj остается в CATALINA_HOME / lib

Я исправил строку импорта в Tmp.java для:

import java.sql.Connection вместо com.mysql.jdbc.Connection

Теперь, когда я получаю новую ошибку, когда нажимаю кнопку отправки в браузере.

Cannot create JDBC driver of class '' for connect URL 'null'

Я попытался записать журнал:

makun /home/makun/tomcat/apache-tomcat-6.0.26/logs -> tail -f localhost.2010-08-30.log

и ничего не появляется, когда я нажимаю кнопку отправки. (это правильный журнал, я думаю, так как другие страницы, которые имеют ошибку, будут выводить сообщение в журнале)

UPDATE

Я не уверен, почему, но он начал работать, когда я пытался распечатать трассировку стека исключений в моем журнале. Я перезагружал Tomcat со страницы менеджера так много раз, что это могло вызвать что-то странное и получать ту же страницу ошибок, даже если я изменил код (это было ужасно, давая мне 404 и 500 взаимозаменяемо. мои шаги, описанные в разделе вопросов, похоже, работали (после исправления нескольких предложенных вещей)

Ответы [ 2 ]

3 голосов
/ 31 августа 2010

Это исключение говорит вам, что он не может найти класс com.mysql.jdbc.Connection при исследовании объявленных полей сервлета во время его загрузки / создания экземпляра с целью сбора любых аннотаций для кэша аннотаций.

Вы должны использовать java.sql.Connection, а не com.mysql.jdbc.Connection. Фактически, все ваш код JDBC должен импортировать / использовать java(x).sql интерфейсы / классы * только 1013 * . В противном случае ваш код JDBC тесно связан с используемым DB и драйвером JDBC и не может использоваться повторно с другими DB и / или драйверами, что нарушает всю абстрактную идею JDBC.


Тем не менее, объявление Connection как переменной экземпляра сервлета является крайне плохой идеей. Сервлет создается только один раз и распределяется между всеми запросами в течение времени жизни веб-приложения. Вы должны получить и закрыть соединение в кратчайшей возможной области , т. Е. Уже в том же методическом блоке. Еще лучше, поместите всю логику JDBC в повторно используемый класс DAO, который вы просто импортируете в свой сервлет.

Смотри также:

1 голос
/ 31 августа 2010

Класс, который он не может найти "com.mysql.jdbc.Connection", должен находиться в mysql-connector-java-5.1.13-bin.jar.Я думаю, что tomcat должен быть в состоянии забрать его из $ CATALINE_HOME / lib.Итак, из того, что вы говорите, это "должно" работать ...

Возможно, проверьте, что пользователь tomcat работает с правами на чтение файла?Возможно, файл jar поврежден - возможно, по ftp в текстовом режиме?Вы уверены, что CATALINA_HOME является /home/makun/tomcat/apache-tomcat-6.0.26 - возможно, проверьте сценарии запуска tomcat, чтобы узнать, настроен ли он где-то еще?

можно попробовать поместить файл jar в web-inf / lib.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...