【问题标题】:Trying to set up Tomcat and JDBC connection pooling: Communications Link Failure尝试设置 Tomcat 和 JDBC 连接池:通信链接失败
【发布时间】:2017-01-12 07:04:20
【问题描述】:

来自 tomcat 窗口的完整错误消息:

[localhost-startStop-1] ERROR org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator - HHH000342: Could not obtain connection to query metadata: Cannot create PoolableConnectionFactory (Communications link failure)

基本上每次我启动 tomcat 时,它都会在尝试与远程 linux 服务器上的 mysql 数据库建立 jdbc 连接时出现通信链接故障(在我必须 VPN 进入的专用网络上),我想不通找出原因。

谁能告诉我为什么会出现此错误以及如何解决它。一如既往,感谢您的时间和帮助!

已经采取的步骤

。配置 MySQL 以允许远程连接到数据库。我尝试将 my.cnf 中的绑定地址设置为 0.0.0.0 以及数据库所在服务器的 IP,但在这两种情况下都会出现相同的错误。我添加了一个新用户并使用 GRANT ALL PRIVILEGES 命令让该用户从 127.0.0.1 和托管数据库的服务器的 IP 远程访问数据库。

。尝试完全停用我的防火墙,但没有效果

。从我本地计算机上的 intellij 中,我尝试使用持久性菜单中的设置用户和密码建立与数据库的 JDBC 连接。这在我已经通过 VPN 连接到专用网络时有效,并且我能够很好地查看数据库。

。在我的 tomcat 文件夹中使用此资源标记更新了 server.xml

<Resource name="jdbc/mydb"
      global="jdbc/mydb"
      auth="Container"
      type="javax.sql.DataSource"
      driverClassName="com.mysql.jdbc.Driver"
      url="jdbc:mysql://(IP-address of the database server):3306/DBname"
      username="user"
      password="password"
      maxActive="10"
      maxIdle="10"
      minIdle="5"
      maxWait="10000"/>

。使用此资源链接更新了 tomcat 文件夹中的 context.xml 文件:

<ResourceLink name="jdbc/mydb" 
       global="jdbc/mydb"
       auth="Container"
       type="javax.sql.DataSource" />

。更新了我的 hibernate.cfg.xml 文件如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

    <!-- For Database Access -->
    <property name="hibernate.connection.url">jdbc:mysql://(IP-address of database server):3306/DBname</property>
    <property name="connection.datasource">java:comp/env/jdbc/mydb</property>
    <property name="hibernate.current_session_context_class">thread</property>

    <!-- List of XML mapping files -->
    <mapping resource="db-full.hbm.xml"/>
    <mapping class="POJOs.Pojo1"/>
    <mapping class="POJOs.Pojo2"/>
    <mapping class="POJOs.Pojo3"/>
    <mapping class="POJOs.Pojo4"/>
    <mapping class="POJOs.Pojo5"/>
    <mapping class="POJOs.Pojo6"/>
    <mapping class="POJOs.Pojo7"/>

</session-factory>
</hibernate-configuration>

。更新了我的 dispatcher-servlet.xml 如下:

    <beans:beans xmlns="http://www.springframework.org/schema/mvc"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:beans="http://www.springframework.org/schema/beans"
                 xmlns:context="http://www.springframework.org/schema/context"
                 xmlns:tx="http://www.springframework.org/schema/tx"
                 xsi:schemaLocation="http://www.springframework.org/schema/mvc
              http://www.springframework.org/schema/mvc/spring-mvc.xsd
              http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/context
              http://www.springframework.org/schema/context/spring-context.xsd
              http://www.springframework.org/schema/tx
              http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

    <annotation-driven />
    <context:component-scan base-package="springmvc.controllers, data.service, data.DAO" />

    <resources mapping="/resources/**" location="resources" />

    <beans:bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <beans:property name="url" value="jdbc:mysql://(IP-address of database server):3306/DBname" />
        <beans:property name="username" value="user" />
        <beans:property name="password" value="password" />
    </beans:bean>

    <beans:bean id="sessionFactory"
          class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <beans:property name="dataSource" ref="dataSource" />
        <beans:property name="configLocation" value="WEB-INF/resources/hibernate.cfg.xml" />
    </beans:bean>

    <tx:annotation-driven />
    <beans:bean id="transactionManager"
          class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <beans:property name="sessionFactory" ref="sessionFactory" />
    </beans:bean>
</beans:beans>

。更新了我的 web.xml 如下:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd
     http://xmlns.jcp.org/xml/ns/javaee/web-common_3_1.xsd"
     version="3.1">

<display-name>Web Application</display-name>


<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/resources/application-context.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>springDispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/springDispatcher-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>springDispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!-- RESOURCE REF (TRIED RUNNING WITH AND WITHOUT) -->
<!--<resource-ref>-->
    <!--<description>Connection Pool</description>-->
    <!--<res-ref-name>jdbc/mydb</res-ref-name>-->
    <!--<res-type>javax.sql.DataSource</res-type>-->
    <!--<res-auth>Container</res-auth>-->
<!--</resource-ref>-->

</web-app>

。更新pom.xml如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.project.procect-name</groupId>
    <artifactId>ProjectName</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <org.springframework.version>4.3.2.RELEASE</org.springframework.version>
        <hibernate.version>5.2.1.Final</hibernate.version>
        <mysql.connector.version>5.5.49</mysql.connector.version>
        <hibernate.version>5.2.1.Final</hibernate.version>
        <mysql.connector.version>5.5.50</mysql.connector.version>

    </properties>

    <dependencies>
        <!-- JDBC Driver -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.35</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.10.2.RELEASE</version>
        </dependency>

        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.1.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.1.1.Final</version>
        </dependency>
        <dependency>
            <groupId>javax.transaction</groupId>
            <artifactId>jta</artifactId>
            <version>1.1</version>
        </dependency>

        <!-- HSQL Database -->
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>2.3.2</version>
        </dependency>

        <!-- JSON -->
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20160810</version>
        </dependency>

        <!-- Jackson To Convert java to JSON -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.1</version>
        </dependency>

        <!-- Application View -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- Apache Commons DBCP (Connection Pooling) -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-dbcp2</artifactId>
            <version>2.0</version>
        </dependency>

        <!-- Log4J -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>ROOT</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>

                <version>2.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <webXml>src\main\webapp\WEB-INF\web.xml</webXml>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

【问题讨论】:

    标签: hibernate spring-mvc tomcat jdbc remote-access


    【解决方案1】:

    如果您使用以下属性,则不需要声明JNDI 变量。

    hibernate.connection.url
    hibernate.connection.username
    hibernate.connection.password
    hibernate.connection.driver_class
    

    示例:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                                             "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory name="">
            <!-- SQL dialect -->
            <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
            <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
            <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/gocommerce</property>
            <property name="hibernate.connection.username">root</property>
            <property name="hibernate.connection.password">root</property>
            <property name="hibernate.connection.pool_size">20</property>
            <property name="hibernate.current_session_context_class">thread</property>
            <mapping resource="Item.hbm.xml" />
        </session-factory>
    </hibernate-configuration>
    

    如果您想使用JNDI 方法,那么我建议您这样做。

    编辑/创建文件*path_to_your_tomcat_home*/conf/Catalina/*hostname*/*applicationName*.xml,然后像这样声明JNDI变量。

    <?xml version="1.0" encoding="UTF-8"?>
    <Context antiResourceLocking="false" privileged="true" cookies="true">
        <Resource name="datasource" auth="Container" type="javax.sql.DataSource"
            driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://<database-url>/<database-name>"
            username="<username>" password="<password>" />
    </Context>
    

    然后在你的休眠文件中,你可以将数据源指定为java:comp/env/datasource

    由于您已指定数据源本身,您可以跳过hibernate.connection.url 属性。

    参考this answer

    【讨论】:

    • 因此,如果我理解正确,如果您使用上面提到的四个变量,则不需要使用 JNDI 资源。所有这些都需要在 hibernate.cfg.xml 中设置吗?或者只要在调度程序 servlet 的休眠数据源 bean 中指定它们就足够了。目前在 hibernate.cfg.xml 中我只声明了一个 hibernate.connection.url、hibernate.dialect 和 hibernate.connection.driver_class。但是在从 server.xml 和 context.xml 中删除 JNDI 资源和链接并运行后,我得到了同样的错误。 @Jay
    • 您是否确认您的数据库正在运行?试试mysql -u &lt;username&gt; -p --host = &lt;hostname&gt; 命令,看看会发生什么。
    • 是的,当我运行该命令时,我可以正常访问数据库
    • 我已经编辑了我的答案并在其中添加了一个示例。尝试使用完全相同的并检查问题是否仍然存在...
    • 在我的 hibernate.cfg.xml 中尝试该代码并运行后,我得到了同样的错误
    【解决方案2】:

    对于任何想知道的人来说,我无法连接的原因是因为我必须通过 VPN 接入的专用网络只允许某些端口访问数据库。

    在我的情况下,默认 MySQL 端口 3306 在该网络上被阻止,必须更改为允许的端口之一。

    【讨论】:

      猜你喜欢
      • 2012-03-02
      • 2017-07-31
      • 1970-01-01
      • 2018-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-20
      相关资源
      最近更新 更多