Glassfish4 和 MySQL 5.5.38 远程服务器:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信链路故障

Posted

技术标签:

【中文标题】Glassfish4 和 MySQL 5.5.38 远程服务器:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信链路故障【英文标题】:Glassfish4 and MySQL 5.5.38 remote server: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 【发布时间】:2014-12-09 03:07:36 【问题描述】:

我有 2 个亚马逊 ec2 实例。在第一个实例上,我的应用程序在 Glassfish4 应用服务器上运行,而在第二个实例上,我安装了 mysql。我必须连接到层。 我已经将mysql配置为远程服务器,在etc/mysql/my.conf中设置bind-address=0.0.0.0并重启mysql。然后我在 mysql 中创建一个 user@ 并将创建的数据库上的所有权限授予该用户。

在应用层我使用以下 glassfish 命令创建 jdbc 连接池:

create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlDataSource --restype javax.sql.DataSource --property portNumber=3306:password=<PASSWORD>:user=<USER>:serverName=<MYSQL-SERVER-IP>:databaseName=<DATABASE-NAME> <CONNECTION-POOL-NAME>    

然后我在 Glassfish4 上部署我的应用程序。

在我的应用程序中,我使用以下方法:

public Connection getConnection() 
    Connection c = null;
    try 
        Class.forName("com.mysql.jdbc.Driver");
        c = (Connection) DriverManager.getConnection(connectionString,username,password);
     catch (SQLException e) 
        e.printStackTrace();
    catch (ClassNotFoundException e) 
        e.printStackTrace();
    
    return c;
    

我的应用程序也有一个特殊的功能。我使用 JPA 2.0 处理一些数据库实体,而另一些则直接使用 SQL。所以我还有一个persistence.xml,我在其中指定了以下属性:

<property name="javax.persistence.url" value="jdbc:mysql://<MYSQL-SERVER-IP>:3306/<DATABASE-NAME>"/>    

persistence.xml 属性中的 url 与 getConnection() 方法中的 connectionString 用户相同。在persistence.xml 中,我还指定了访问数据库的用户名和密码。

我的应用程序主页显示了两个按钮,一个用于使用 JPA 管理的实体初始化数据库,另一个用于使用 SQL 使用其余实体初始化数据库。第一个成功运行,并且在远程 mysql 服务器上创建了数据库表。但是当我点击第二个按钮时,它会抛出 CommunicationsException。

我在网上和 *** 上阅读了很多关于这个问题的信息,我发现可能有多种原因。我特别阅读了以下讨论:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

并尝试修复几乎所有可能的原因,但似乎一切正常。

在我看来,它应该与 JDBC 驱动程序有关。我还尝试将 mysql JDBC 连接器放在 glassfish4/glassfish/lib 文件夹中,但不起作用。将它放在应用程序类路径中也不起作用。

请原谅我的英语,如果我忘记在问题中指定某些内容。我希望我的问题符合***的规则,因为我刚刚注册,这是我的第一篇文章。

提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

根据您的问题提供一些提示:

然后我在 mysql 中创建一个 user@ 并将创建的数据库上的所有权限授予该用户。

MySQL 身份验证机制验证用户+主机的组合,因此您需要确保您尝试连接的主机允许这样做。例如,一个非常常见的错误是这样创建用户:

CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';

如果您尝试从其他主机连接到 MySQL,那么您将不会成功。详情请见MySQL - Adding user account。


在应用层我创建了 jdbc 连接池 [...]

看起来没问题,但是您还应该将此池作为具有正确 JNDI 名称的 JDBC 资源使用(即:jdbc/ConnectionPoolName,这样您就可以通过使用注入直接在您的应用程序中使用DataSource。参见@ 987654322@。如果您同时使用 JPA 和 JDBC,这将有效。


我的应用程序也有一个特殊的功能。我处理一些数据库 实体使用 JPA 2.0,而其他一些直接使用 SQL。

如果你使用JPA,资源必须设置在persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="MyPU" transaction-type="JTA">
    <jta-data-source>jdbc/ConnectionPoolName</jta-data-source>
    <properties />
  </persistence-unit>
</persistence>

如果您使用纯 JDBC API,则可以通过在 bean 中使用 @Resource 来注入 DataSource,如下所示:

@Stateless
public class MyJdbcBean 

    @Resource(lookup = "jdbc/ConnectionPoolName")
    private DataSource dataSource;

    public Connection getConnection() 
        if (dataSource != null) 
            return dataSource.getConnection();
         else 
            Exception ex = new ExceptionInInitializerError("Couldn't initialize data source!");
            Logger.getLogger(MyJdbcBean.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
            throw ex;
        
    


我还尝试将 mysql JDBC 连接器放在 glassfish4/glassfish/lib 文件夹中,但不起作用。也放进去 应用程序类路径不起作用。

根据我的经验,JDBC 连接器必须放在域的lib/ext 文件夹中,即:glassfish-4.0/glassfish/domains/domain1/lib/ext

【讨论】:

关于我检查过的主机,我设置了正确的用户+主机对。 jdbc 资源是在persistence.xml 中创建和设置的,实际上使用jpa 管理的实体是正确创建的。但是当我调用 c = (Connection) DriverManager.getConnection(connectionString,username,password);它返回空值。所以我应该使用 SQL 创建的实体没有被创建!这真的很奇怪!还因为如果我尝试在本地运行应用程序(本地 mysql glassfish4 实例),一切正常!我会尝试将连接器放在正确的文件夹中并通知您。 将 mysql-connector-java-5.1.33-bin.jar 放入 glassfish-4.0/glassfish/domains/domain1/lib/ext 并重新启动 glassfish4 不起作用。 server.log 还报告以下内容:上一个成功发送到服务器的数据包是 0 毫秒前。驱动没有从服务器收到任何数据包。 您是否按照我的建议创建了 JDBC 资源?请注意DriverManager.getConnection() 不再适合使用 JDBC,它已被DataSource 接口取代,请参阅this article。尝试从 Glassfish ping 数据库池,看看会发生什么。 JPA 正在工作实际上真的很奇怪:根据最后一条评论 Glassfish 无法连接到服务器。 @MicheleGuerriero 使用 glassfish 命令 ping-connection-pool 成功。我认为 glassfish 能够连接到服务器,因为创建了使用 JPA 数据库表。也许问题出在代码中,我必须按照您所说的那样使用 DataSource,但这不是我的应用程序,虽然我被允许修改代码,但它应该是最后的机会。现在,我什至想修改应用程序代码,但我不明白为什么如果我在本地机器上运行所有程序,一切正常......无论如何我会尝试使用 DataSource 并让你知道。 我用建议的 su 替换了我的 getConnection(),并且我在查找字段中指定了我的 JDBC 资源(我在 persistence.xml 中指定的相同 JDBC 资源),但是由于某些原因失败了当我调用 getConnection() dataSource=null 并且抛出 ExceptionInInitializerError 时。我还在我的课程中添加了@Stateless 注释,但什么都没有。你觉得有什么遗​​漏吗?

以上是关于Glassfish4 和 MySQL 5.5.38 远程服务器:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信链路故障的主要内容,如果未能解决你的问题,请参考以下文章

免费架构之ADF12C essentials+MYSQL5.5.40+GLASSFISH4.1

mysql基础知识

centos6.5 删除lamp

Glassfish 4没有资源的密码凭据

PHP 备份还原 MySql 数据库

休息,glassfish4 shiro 启用工作样本