java - 当项目部署在 tomcat 上时 JDBC 数据源不工作

标签 java mysql eclipse tomcat mariadb

我开发了一个通过 JDNI 数据源调用 MariaDB 数据库的 servlet。当我在 eclipse 中运行的 tomcat 服务器上的 eclipse 中运行 web 项目时,这工作正常。

但是,当我在 eclipse 外部的 tomcat 服务器上部署项目时,使用 WAR 文件,相同的 servlet 不起作用。出于测试目的,该项目还包含另一个直接连接(即不使用 JDNI 数据源)到同一个 mariaDB 的 servlet,即使部署到 eclipse 外部的 tomcat 服务器,它也能正常工作。 关于可能出现的问题,我的想法已经用完了,如果有人能说明一些问题,我将不胜感激。

配置信息:

  • 操作系统:macOS High Sierra
  • tomcat 版本:8.5
  • eclipse:Neon.2.,发布 4.6.2
  • Java:8
  • MariaDB 驱动程序:mariadb-java-client-2.2.0

在 eclipse 之外,驱动程序在两个位置:

  • /tomcat-文件夹/lib
  • /tomcat-folder/webapps/my-app/WEB-INF/lib(来自 WAR 文件)

我已将以下资源引用添加到应用程序 web.xml 文件:

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

我已将以下资源添加到/tomcat-folder/contf/context.xml:

<Resource name="jdbc/MYDB” auth="Container" type="javax.sql.DataSource"
               maxTotal="100" maxIdle="30" maxWaitMillis="10000"
               username="root" password="" driverClassName="org.mariadb.jdbc.Driver"
               url="jdbc:mariadb//localhost:3306/MYDB”/>

我得到的错误是:

java.sql.SQLException: Cannot create JDBC driver of class 'org.mariadb.jdbc.Driver' for connect URL 'jdbc:mariadb//localhost:3306/MYDB'
    at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createConnectionFactory(BasicDataSource.java:2167)
    at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:2037)
    at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1543)
    at DBConfigTest.getConnection(DBConfigTest.java:123)
    at DBConfigTest.doGet(DBConfigTest.java:59)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:789)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1437)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.sql.SQLException: No suitable driver
    at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createConnectionFactory(BasicDataSource.java:2158)
    ... 28 more
java.lang.NullPointerException
    at DBConfigTest.doGet(DBConfigTest.java:61)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:789)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1437)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

servlet代码如下:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class DBConfigTest extends HttpServlet{
   public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

      // JDBC driver name and database URL
     // static final String JDBC_DRIVER = "org.mariadb.jdbc.Driver";  
     // static final String DB_URL="jdbc:mariadb://localhost/MYDB"+"?user=root&password=";

      //  Database credentials
     // static final String USER = "root";
     // static final String PASS = "";

      // Set response content type
      response.setContentType("text/html");
      PrintWriter out = response.getWriter();
      String title = "Database Result";

      String docType =
         "<!doctype html public \"-//w3c//dtd html 4.0 " + "transitional//en\">\n";

      out.println(docType +
         "<html>\n" +
         "<head><title>" + title + "</title></head>\n" +
         "<body bgcolor = \"#f0f0f0\">\n" +
         "<h1 align = \"center\">" + title + "</h1>\n");

   // Execute SQL query
      //Statement stmt=null;
      //Connection conn=null;
      Connection connection=null;
      PreparedStatement statement=null;

      try {
         // Register JDBC driver
         //Class.forName("org.mariadb.jdbc.Driver");

         // Open a connection
         //conn = DriverManager.getConnection("jdbc:mariadb://localhost/MYDB"+"?user=root&password=");

                connection = getConnection();
              String sql = "SELECT * FROM  ingredient";
              statement = connection.prepareStatement(sql);
              ResultSet rs = statement.executeQuery();

         // Execute SQL query
         /*stmt = conn.createStatement();
         String sql;
         sql = "SELECT * FROM  ingredient";
         ResultSet rs = stmt.executeQuery(sql);*/

         // Extract data from result set
         while(rs.next()){
            //Retrieve by column name
            int id  = rs.getInt("ingredient_id");
            String code = rs.getString("ingredient_code");
            String description = rs.getString("ingredient_description");

            //Display values
            out.println("ID: " + id + "<br>");
            out.println(", Code: " + code + "<br>");
            out.println(", Description: " + description + "<br>");

         }
         out.println("</body></html>");

         // Clean-up environment
         rs.close();
         statement.close();
         connection.close();
      } catch(SQLException se) {
         //Handle errors for JDBC
         se.printStackTrace();
      } catch(Exception e) {
         //Handle errors for Class.forName
         e.printStackTrace();
      } finally {
         //finally block used to close resources
         try {
            if(statement!=null)
               statement.close();
         } catch(SQLException se2) {
         } // nothing we can do
         try {
            if(connection!=null)
            connection.close();
         } catch(SQLException se) {
            se.printStackTrace();
         } //end finally try
      } //end try
   }



   private Connection getConnection() {
        Connection connection = null;
        try {
          /*InitialContext context = new InitialContext();
          DataSource dataSource = (DataSource) context.lookup("jdbc/MYDB");
          connection = dataSource.getConnection();*/

            Context initContext = new InitialContext();
            Context envContext  = (Context)initContext.lookup("java:/comp/env");
            DataSource ds = (DataSource)envContext.lookup("jdbc/MYDB");
            connection = ds.getConnection();


        } catch (NamingException e) {
          e.printStackTrace();
        } catch (SQLException e) {
          e.printStackTrace();
        }
        return connection;
      }
}

最佳答案

以下示例中的 url 应为 url="jdbc:mariadb://localhost:3306/MYDB"。JDBC URL 中的冒号 (:) 在 mariadb 之后和//之前丢失。

<Resource name="jdbc/MYDB” auth="Container" type="javax.sql.DataSource"
               maxTotal="100" maxIdle="30" maxWaitMillis="10000"
               username="root" password="" driverClassName="org.mariadb.jdbc.Driver"
               url="jdbc:mariadb//localhost:3306/MYDB”/>

关于java - 当项目部署在 tomcat 上时 JDBC 数据源不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48916748/

相关文章:

java - HTTP 状态 404 错误或 web.xml 错误不知道

使用 Guava FutureCallback 接口(interface)进行 Java 多线程编程

php - 在 Laravel 5 中,迁移到删除组合唯一键不起作用

java - Android - 迁移到 HoloEverywhere

java - Eclipse 不导入 Android 项目

php - 如何在 AJAX 上接收 PHP 表,并将其显示在 DIV 中?

java - 为什么我得到 java.net.SocketException : Connection reset

java - 如何使用 Joda 时间找到最近的月末日期?

java - JAX-WS到底是什么?

mysql - SQL在指定记录后给出X记录