【问题标题】:Java (Grails) cannot connect to MySQL remotely nor locally, but MySQL command line canJava(Grails)无法远程或本地连接到 MySQL,但 MySQL 命令行可以
【发布时间】:2015-01-17 13:39:45
【问题描述】:

我在 Windows 和 Linux 上设置了许多 MySQL 数据库,并将许多 Java 应用程序连接到它们没有问题。

这个特别的人让我发疯,我检查了所有常见的嫌疑人,然后一无所获。

问题:

我在 Ubuntu 14 上安装了 MySQL 5.6。我可以通过 MySQL 命令行从本地计算机或远程 PC 很好地连接到它,但我无法将我的 Grails 应用程序连接到数据库,也不能在 MySQL 所在的本地服务器上的 Tomcat 中运行在我的本地 PC 上安装或以开发模式运行。 Grails 应用程序可以很好地连接到在我的 PC 上运行的本地 MySQL,但不是在 Ubuntu 上运行的那个。

Ubuntu MySQL 配置:

  1. 通过 apt-get install mysql-server-5.6 在 Ubuntu 14 上安装 MySQL 5.6
  2. 创建数据库 mydb;
  3. 创建由“mypass”标识的用户“myuser”@“%”;
  4. 授予 * 上的所有权限。 * 到 'myuser'@'%';
  5. 绑定地址在my.cnf中被注释掉,所以绑定到所有ip。
  6. 服务 mysql 重启。
  7. iptables 没有运行。
  8. 没有为此服务器配置 ISP 防火墙,一切都打开了。

测试连接:

  1. 来自本地服务器:“mysql -u myuser -p mydb” - 工作并可以创建表等。
  2. 如上从远程 PC 运行窗口通过:“mysql -u myuser -p -h x.x.x.x mydb”其中 x.x.x.x 是我的服务器的 IP。工作正常。可以创建表格等。

以上暗示 MySQL 运行良好,没有防火墙或网络问题。

Grails“DataSource.groovy”配置

dataSource {
    pooled = true
    driverClassName = "com.mysql.jdbc.Driver"
    dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
} 
environments {
    development {
        dataSource {
            dbCreate = "create-drop"
            url = "jdbc:mysql://x.x.x.x:3306/mydb"
            username = "myuser"
            password = "mypass"
        }
    }
}

注意:

  • 也试过了:url = "jdbc:mysql://x.x.x.x/mydb"
  • JDBC jar 为:mysql-connector-java-5.1.34.jar
  • 使用的Java是:Windows jkd1.7.0_60

错误

Message: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
    Line | Method
->>  377 | handleNewInstance             in com.mysql.jdbc.Util
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1036 | createCommunicationsException in com.mysql.jdbc.SQLError
|    338 | <init> . . . . . . . . . . .  in com.mysql.jdbc.MysqlIO
|   2232 | coreConnect                   in com.mysql.jdbc.ConnectionImpl

日志: 服务器上的文件 /var/log/upstart/mysql.log 和 var/log/mysql/error.log 中没有任何相关内容。

百万美元的问题是: 为什么 MySQL 能够连接,而 JDBC 却不能?它们的工作方式(本地和远程机器)有什么区别?

This post关于这个问题的信息最多,但我没有找到任何解决方案。

也试过这个:

properties {
    maxActive = -1
    minEvictableIdleTimeMillis=1800000
    timeBetweenEvictionRunsMillis=1800000
    numTestsPerEvictionRun=3
    testOnBorrow=true
    testWhileIdle=true
    testOnReturn=true
    validationQuery="SELECT 1"
}

在与数据库相同的服务器上在 Tomcat 上运行 Grails 战争

我有或多或少相同的错误,但不同的Java,不同的操作系统,不同的连接方式。

Tomcat7 /var/lib/tomcat7/conf/context.xml

<Resource name="myresource" auth="Container" type="javax.sql.DataSource"
    maxActive="50" maxIdle="5" maxWait="10000"
    username="myuser" password="mypass" driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/mydb"/>

Grails 配置

environments {
    production {
        dataSource {
            dbCreate = "update"
            jndiName = "java:comp/env/myresource"
            pooled = true
            driverClassName = "com.mysql.jdbc.Driver"
            dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
            properties {
                maxActive = -1
                minEvictableIdleTimeMillis=1800000
                timeBetweenEvictionRunsMillis=1800000
                numTestsPerEvictionRun=3
                testOnBorrow=true
                testWhileIdle=true
                testOnReturn=true
                validationQuery="SELECT 1"
            }
        }
    }
}

/var/log/tomcat7/catalina.out 中的错误

2015-01-16 23:18:41,425 [localhost-startStop-1] ERROR pool.ConnectionPool  - Unable to create initial connections of pool.
java.sql.SQLException: Driver:com.mysql.jdbc.Driver@52fc036d returned null for URL:jdbc:h2:mem:grailsDB;MVCC=TRUE;LOCK_TIMEOUT=10000
        at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:296)
        at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:182)

有趣的是,上面提到了 h2:mem db,但我认为这只是一个红鲱鱼,它可能在尝试连接到 MySQL db 后尝试这样做。 DataSource.groovy 文件中的任何地方都没有提及 h2 db。

注意:

服务器(与 MySQL 服务器相同)上的 Java 是 OpenJDK,而不是 Oracle 的:

# apt-get install openjdk-7-jre-headless
# java -version
java version "1.7.0_65"
OpenJDK Runtime Environment (IcedTea 2.5.3) (7u71-2.5.3-0ubuntu0.14.04.1)
OpenJDK 64-Bit Server VM (build 24.65-b04, mixed mode)

JDBC(不知道如何验证版本)

# apt-get install libmysql-java
# cp /usr/share/java/mysql.jar /usr/share/tomcat7/lib

我在 my.cnf 中尝试了以下绑定选项(单独,重启)

bind-address           = 127.0.0.1
bind-address           = x.x.x.x (i.e. my servers external fixed ip)
bind-address           = 0.0.0.0
# bind-address           = 127.0.0.1

都给出相同的错误。在开发服务器上,我通常将它的绑定地址注释掉,以便它侦听所有接口。

我也检查过:

TOMCAT7_SECURITY=no

在 /etc/init.d/tomcat7

【问题讨论】:

  • 它从命令行而不是 Grails 工作的原因是 Grails 配置错误,但不清楚在哪里。在错误中包含jdbc:h2:mem:grailsDB;MVCC=TRUE;LOCK_TIMEOUT=10000 并不是一个红鲱鱼。这表明没有找到数据源信息,因此 Grails 使用默认值。试试grails cleangrails compile - 我的猜测是由于拼写错误而无法编译,完全重新编译应该会显示这一点。我会更进一步,rm -rf target 而不是运行 clean - 除了重新编译之外,这将删除所有生成的文件并触发插件重新安装。
  • 尝试运行grails console并执行println ctx.grailsApplication.config.dataSource。将其关闭并运行 grails prod console 并再次运行。这将向您展示不同环境的数据源的已解析设置。
  • grails 控制台是个好主意。但是,当我使用 prod env (这只是 db 的不同 ip)运行它时,它会给出堆栈跟踪,然后没有控制台出现。当我使用本地 mysql 的 ip 为 dev 运行它时,我得到了控制台,然后输入 println ctx... 就可以了。
  • @BurtBeckwith 破解了!按照你的逻辑,意识到问题出在哪里。我有一个包含所有数据库逻辑的插件核心。我有一个使用该插件的应用程序。我在插件中编辑 DataSource.groovy,以为就是那个。但它在调用应用程序中使用 Datasource.groovy。哇!
  • 是的,Grails 在这方面很烦人——总是做你告诉它做的事情,而不是你想让它做的事情:)

标签: mysql tomcat jakarta-ee grails


【解决方案1】:

我遇到了类似的问题。

只是为了澄清报告的错误日志中的行:

URL:jdbc:h2:mem:grailsDB;MVCC=TRUE;LOCK_TIMEOUT=10000

此数据库连接 URL 似乎是 DataSource 的默认 URL,当您未在自定义 DataSource 中指定任何有效 URL 时使用该 URL。这意味着,当您在日志中看到此 URL 时,您还没有为您的数据库指定任何有效的 URL。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题。 我升级了MySql的依赖版本和驱动类名如下:

    来自:

    mysql:mysql-connector-java:5.1.36

    com.mysql.jdbc.Driver

    到:

    mysql:mysql-connector-java:8.0.18

    com.mysql.cj.jdbc.Driver

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-28
      • 1970-01-01
      • 2017-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-05
      • 2018-07-26
      相关资源
      最近更新 更多