java - JDBC MySQL 连接在某些 Tomcat 上有效,但在其他 Tomcat 上失败并出现 MySQLNonTransientConnectionException

标签 java mysql tomcat jdbc jetty

我有一个通常在 tomcat 上运行的 GWT Web 应用程序项目,但我无法让它可靠地连接到我的 MySQL 数据库。

它适用于以下情况:

  • 从 Eclipse 作为“Web 应用程序”运行
  • 使用 gradle 构建,war 部署在远程 tomcat 6 服务器上
  • 使用 gradle 构建,war 部署在本地 tomcat 7 服务器上

以下情况不起作用

  • 在 gradle 通过 jettyRunWar 任务创建的本地 jetty 上运行(首先构建 war ,然后启动内置 jetty 以将其部署到)
  • 使用 gradle 构建,war 部署在远程 tomcat 7 服务器上

Web 应用程序在所有情况下都可以正常启动,但在最后两种情况下第一次数据库访问失败并出现以下异常:

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2575)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2311)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:834)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:416)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:347)
at com.mysql.jdbc.jdbc2.optional.MysqlDataSource.getConnection(MysqlDataSource.java:443)
at com.mysql.jdbc.jdbc2.optional.MysqlDataSource.getConnection(MysqlDataSource.java:141)
at com.mysql.jdbc.jdbc2.optional.MysqlDataSource.getConnection(MysqlDataSource.java:111)
    [snip: our code creating the connection to the database]

Caused by: java.lang.NullPointerException
at com.mysql.jdbc.Buffer.<init>(Buffer.java:55)
at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1740)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1290)
at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2493)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2526)
... 44 more

我也回顾了几个月前的提交历史,但找不到没有问题的版本。但是,我很确定它曾经使用 gradle 的 jettyRunWar 命令运行而没有问题。

这里是数据库连接的相关代码:

public static Connection getConnection(String host, int port, String database, String user, String password) throws SQLException
{
    MysqlDataSource dataSource = new MysqlDataSource();
    dataSource.setServerName(host);
    dataSource.setPort(port);
    dataSource.setDatabaseName(database);
    dataSource.setUser(user);
    dataSource.setPassword(password);
    dataSource.setConnectTimeout(Preferences.MYSQL_CONNECTION_TIMEOUT);
    return dataSource.getConnection();
}

如您所见,我在多个环境中进行了尝试,并尝试了多个版本的代码(例如,使用不同的 GWT jar 等),但我仍然不知道为什么它在某些配置中有效,但在其他配置中无效。

知道问题出在哪里吗?

最佳答案

从 5.1.17 版本开始的 mysql 驱动程序会出现此错误。降级到 5.1.16 为我解决了这个问题。

编辑:我在 mysqlbug 跟踪器 ( http://bugs.mysql.com/bug.php?id=72630 ) 中提交了一个与此相关的错误。我得到了非常快的回应,原因可能是一些不受支持的编码异常。这对我来说是正确的,所以在修复 file.encoding 系统属性(使用 -Dfile.encoding=UTF-8 运行 tomcat)之后,一切都按预期工作。

关于java - JDBC MySQL 连接在某些 Tomcat 上有效,但在其他 Tomcat 上失败并出现 MySQLNonTransientConnectionException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22201536/

相关文章:

tomcat - 如何正确自动以窗口服务方式运行Tomcat 8?

session - tomcat如何保持 session

java - 如果java可以编译代码,为什么还要解释它?

java - 使用 P 命名空间配置 Hibernate XML

Mysql - 通过查询更新表。重复 key 更新不起作用

MySQL基于if的where语句

mysql - 在mysql中使用单个where条件和单个关键字搜索表的所有列

java - 如何停止由 org.asynchttpclient 创建的线程以防止内存泄漏?

java - 将 spring 请求主体转换为对象列表

java - 在布局之间添加阴影