首页 > 解决方案 > 连接到 MySQL 的 Java 异常

问题描述

已解决 MySQL JDBC 驱动程序的最新版本显然试图创建 SSL 连接。工作的应用程序没有定义 javax.net.ssl.keystore (和其他)值,所以(我假设)它恢复到非 SSL 连接。失败的应用程序确实定义了所有密钥库/证书参数,然后连接尝试失败 - 仍然不确定确切原因,如果有人能启发会感激。抛出的异常也可能提供更多信息。

无论如何,将“&useSSL=false&allowPublicKeyRetrieval=true”添加到连接参数对这两个应用程序都有效。(虽然对于任何生产应用程序来说都不是一个很好的设置,但可以用于这个 POC!)

============= 原帖如下=========

这让我难过了几天!AWS 服务器 (86_64)、Fedora 29、Java 8 (1.8.0_201-b09)、MySQL - 全部升级到最新版本。MySQL 在同一台服务器上运行。驱动:com.mysql.cj.jdbc.Driver

连接参数:jdbc:mysql://172.31.10.222:3306?user=xxxx&password=xxxx。(IP 是此服务器的 AWS 私有 IP。)

有 2 个不同的实用程序 - 单独的“主要”例程,但都在同一个 JAR 文件中。第一个完美运行,第二个中止并粘贴在下面的堆栈。这在数十次试验中是一致的,但有微小的变化。

不同的主例程都使用堆栈跟踪中显示的“connectToDB”方法。对此进行检测以记录两种情况下驱动程序的所有参数和类名,并验证它们是否相同。

已经尝试/验证:

这些是 2 种不同的“主要”方法,但在尝试连接到数据库之前,除了加载一些属性(来自相同的属性文件)之外,别无其他。然后他们执行相同的 connectToDB 例程。

上下文中的某些东西必须有所不同!希望这里的人至少可以提供一些关于在哪里看的提示!

谢谢

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174)
        at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
        at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:835)
        at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:455)
        at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240)
        at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:207)
        at spc.tools.spcConnection.connectToDB(spcConnection.java:692)
        at spc.tools.spcConnection.connectToLocalDB(spcConnection.java:1418)
        at spc.tools.spcConnection.loadAllConnectionsOK(spcConnection.java:1112)
        at spc.tools.spcConnection.initOneTime(spcConnection.java:1012)
        at spc.tools.spcConnection.init(spcConnection.java:194)
        at spc.ops.spcServerBase.environmentOK(spcServerBase.java:367)
        at spc.ops.spcServerBase.environmentOK(spcServerBase.java:342)
        at spc.run.daemon.spcDaemon.main(spcDaemon.java:1082)
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: 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.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
        at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167)
        at com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:351)
        at com.mysql.cj.protocol.a.NativeAuthenticationProvider.negotiateSSLConnection(NativeAuthenticationProvider.java:777)
        at com.mysql.cj.protocol.a.NativeAuthenticationProvider.proceedHandshakeWithPluggableAuthentication(NativeAuthenticationProvider.java:486)
        at com.mysql.cj.protocol.a.NativeAuthenticationProvider.connect(NativeAuthenticationProvider.java:202)
        at com.mysql.cj.protocol.a.NativeProtocol.connect(NativeProtocol.java:1442)
        at com.mysql.cj.NativeSession.connect(NativeSession.java:165)
        at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:955)
        at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:825)
        ... 11 more
Caused by: java.net.SocketException: Broken pipe (Write failed)
        at java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
        at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
        at sun.security.ssl.OutputRecord.writeBuffer(OutputRecord.java:431)
        at sun.security.ssl.OutputRecord.write(OutputRecord.java:417)
        at sun.security.ssl.SSLSocketImpl.writeRecordInternal(SSLSocketImpl.java:879)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:850)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:720)
        at sun.security.ssl.Handshaker.sendChangeCipherSpec(Handshaker.java:1144)
        at sun.security.ssl.ClientHandshaker.sendChangeCipherAndFinish(ClientHandshaker.java:1280)
        at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1190)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:369)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
        at com.mysql.cj.protocol.ExportControlled.performTlsHandshake(ExportControlled.java:315)

==================================================== ==== 新信息 =====

以下是 connectToDB 方法的关键行(回复下面的评论):

Driver dvr = (Driver)Class.forName(info.sDBDriver).newInstance();
if(dvr!=null) conn = dvr.connect(accessString(), null);

验证了预期的驱动程序,并且 accessString() 返回了 'jdbc:mysql:...' 字符串,如上。执行上面的第二行会引发异常。

从原始帖子开始,在这些行之前输入代码以运行“netstat -ln”并将结果发布到日志中。这显示了端口 3306 的活动侦听器。

标签: javamysqlconnection

解决方案


如果您可以发布 connectToDB() 方法,那就太好了。

根据这句话“第一个完美运行,第二个中止并粘贴在下面的堆栈。”,您必须在第一个 connectToDB() 调用中关闭了数据库连接。

因此,由于第一次调用终止了数据库连接,因此第二次调用被中断。

设置的好方法是对数据库对象使用依赖注入。

希望这可以帮助!


推荐阅读