java - Ubuntu,Java,找不到适合 jdbc :postgresql 的驱动程序

标签 java sql postgresql jsp ubuntu

我已经创建了一个 JSP 服务器 (tomcat) 并将其链接到我的 Eclipse IDE。我还创建了一个 PostgreSQL 服务器,并试图找出如何通过我的 JSP 服务器连接到它。

这是我的 JSP 文件的样子:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <%@ page import="helloWorldJSP.Test" %>
    <%@ page import="helloWorldJSP.SQLTest" %>
</head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
    //Test testThing = new Test();  
    //out.println( testThing.caps("thing") );
    SQLTest test = new SQLTest();
    System.out.println("FINISH");
%>


</body>
</html>

我已经对其进行了测试并且它有效,所以我认为错误不在该页面中。

这是我的 SQLTest 类的代码:

package helloWorldJSP;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class SQLTest 
{
    public SQLTest() 
    {
        Connection conn = null;
        System.out.println("STARTING");

        try 
        {

            String url = "jdbc:postgresql://localhost:5432/deama_db";
            String user = "deama1295";
            String password = "1295";

            conn = DriverManager.getConnection(url, user, password);
            if (conn != null) 
            {
                System.out.println("Connected to the database postgres");
            }
        }
        catch (SQLException ex) 
        {
            System.out.println("An error occurred. Maybe user/password is invalid");
            ex.printStackTrace();
        }
    }
}

在我的 tomcat 服务器 lib 文件夹中,我查找了 JDBC 驱动程序,它就在那里。 我正在从 virtualBox 虚拟机运行 Ubuntu-18.10-desktop-amd64。

我已经尝试将数据库和用户名更改为“postgres”(我相信这是默认设置?)但这并没有改变我的错误(我很确定我将 postgres 的密码设置为 1295)。

这是完整的错误信息:

java.sql.SQLException: No suitable driver found for jdbc:postgresql://localhost/deama_db
    at java.sql.DriverManager.getConnection(DriverManager.java:689)
    at java.sql.DriverManager.getConnection(DriverManager.java:208)
    at helloWorldJSP.SQLTest.<init>(SQLTest.java:26)
    at org.apache.jsp.NewFile_jsp._jspService(NewFile_jsp.java:127)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    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:493)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

最佳答案

根据 JNDI Datasources 上的 Tomcat 8 文档,使用 DriverManager 加载驱动程序的默认行为是从 Apache-Tomcat-Home/lib 文件夹中读取它们。否则,您将必须显式注册驱动程序。这基本上与Tomcat的类加载机制有关。以下是文档的摘录:

The JRE Memory Leak Prevention Listener that is included with Apache Tomcat solves this by triggering the drivers scan during Tomcat startup. This is enabled by default. It means that only libraries visible to the listener such as the ones in $CATALINA_BASE/lib will be scanned for database drivers. If you are considering disabling this feature, note that the scan would be triggered by the first web application that is using JDBC, leading to failures when this web application is reloaded and for other web applications that rely on this feature.

Thus, the web applications that have database drivers in their WEB-INF/lib directory cannot rely on the service provider mechanism and should register the drivers explicitly. This behavior should apply to newer versions of Tomcat.

这里的关键是JRE Memory Leak Prevention Listener使用 DriverManager 查找数据库驱动程序时的行为。根据文档,这个监听器:

provides work-arounds for known places where the Java Runtime environment uses the context class loader to load a singleton as this will cause a memory leak if a web application class loader happens to be the context class loader at the time. The work-around is to initialise these singletons when this listener starts as Tomcat's common class loader is the context class loader at that time.

但在你的情况和我的情况下,我能够重现错误,Web 应用程序类加载器与上下文类加载器不同,因此它没有找到驱动程序。所以解决方案是配置监听器以禁用 DriverManager 保护 - 默认值设置为 true。为此,您可以在 Apache-Tomcat-Home/conf/server.xml 文件中将 driverManagerProtection 属性值设置为 false:

<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" driverManagerProtection="false"/>

也就是说,我不认为 DriverManager 是在 Web 服务器中实例化数据库连接的正确方法;数据库连接很昂贵。我建议使用 DataSource,它可以汇集连接并因此提高性能。有关示例,请参阅提供的文档链接。

不过,我确实相信每项技术都有它的用武之地。所以......我会留给你来决定什么对你的情况有效。但至少,您已经有了答案。

关于java - Ubuntu,Java,找不到适合 jdbc :postgresql 的驱动程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53938862/

相关文章:

Java 游戏无法仅在 CMD 中在 Java 中启动

php - 在日期之间循环并显示每个日期的记录

mysql - SQL:每个 GROUP BY 增量

postgresql - HikariCP 未检测到数据库 DNS 更改

sql - 使用 Rails 'contains operator'(或替代方案)搜索多个值

java - 如何使用 Gremlin 和 Java 查询远程 Apache Tinkerpop 图形数据库?

java - 通过对象比较使 mockito 不那么严格

java - Android MediaMetaDataReceiver.setDataSource 上的 IllegalArgumentException

SQL Server 2008查询计划警告 "No Join Predicate",查询需要很长时间

SQL Statement JOIN 只返回有关联的元素