Spring Boot:Jdbc javax.net.ssl.SSLException:在接收对等方的 close_notify 之前关闭入站

新手上路,请多包涵

我目前正在学习有关在 Spring Boot webapp 中实现 JDBC 和使用数据库的更多信息,并且我遇到了写在帖子底部的以下 Stack Trace。

我创建了一个简单的 Employee 模型,我试图在我的 main() 所在的同一个类上执行一些数据库代码。模型和主类是整个项目中仅有的两个 java 文件。我正在尝试实现以下 run() 代码,该代码覆盖接口 CommandLineRunner 中的代码,但我没有得到应该在 log.info(“Part A:”) 之后出现的日志:

 log.info("Part A:")
employees.forEach(employee -> {log.info(employee.toString());
        log.info("part a");});

——我注意到的事情:

我注意到堆栈跟踪开始之前日志的最后一行来自:“Thread-1”而不是“main”。我认为这意味着来自主线程以外的某个线程在正常关闭之前遇到了错误并关闭了连接。

另外,我认为因为 HikariPool 在 “peer’s close_notify” 之前关闭,我认为它指的是 HikariPool 的正常关闭,所以我无法看到我一直试图获取的最后一点日志记录。我想查看的最后一点日志记录是插入到我的数据库中的员工的日志记录。

我想看到的最后一点日志记录应该从这行代码中获取:

 employees.forEach(employee -> {log.info(employee.toString());
        log.info("part a");});

——注意事项:

因为日志中的这一行,我以为我会看到员工插入到我的数据库中,但是当我直接在 MySQL 命令行客户端上查询时,它返回了一个空集:

 2018-11-03 21:08:35.362  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : rows affected: 1

我不明白为什么 在没有向数据库中插入任何内容时一行会受到影响

堆栈跟踪和日志:(下面粘贴的堆栈跟踪实际上又重复了几次,但为简洁起见,我将其切断。)

 2018-11-03 21:08:32.997  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : Starting JdbcTest1Application on KitKat with PID 2408 (C:\Users\Nano\Downloads\jdbc-test1\jdbc-test1\target\classes started by Nano in C:\Users\Nano\Downloads\jdbc-test1\jdbc-test1)
2018-11-03 21:08:33.003  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : No active profile set, falling back to default profiles: default
2018-11-03 21:08:33.770  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : Started JdbcTest1Application in 1.024 seconds (JVM running for 1.778)
2018-11-03 21:08:33.770  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : Creating tables
2018-11-03 21:08:33.770  INFO 2408 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2018-11-03 21:08:34.082  INFO 2408 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2018-11-03 21:08:35.135  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : Inserting Baggins Hopkins
2018-11-03 21:08:35.362  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : rows affected: 1
2018-11-03 21:08:35.362  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : Querying for employee
2018-11-03 21:08:36.065  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : Part A:
2018-11-03 21:08:36.065  INFO 2408 --- [       Thread-1] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
Sat Nov 03 21:08:36 KST 2018 WARN: Caught while disconnecting...

EXCEPTION STACK TRACE:

** BEGIN NESTED EXCEPTION **

javax.net.ssl.SSLException
MESSAGE: closing inbound before receiving peer's close_notify

STACKTRACE:

javax.net.ssl.SSLException: closing inbound before receiving peer's close_notify
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:129)
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:255)
    at java.base/sun.security.ssl.SSLSocketImpl.shutdownInput(SSLSocketImpl.java:645)
    at java.base/sun.security.ssl.SSLSocketImpl.shutdownInput(SSLSocketImpl.java:624)
    at com.mysql.cj.protocol.a.NativeProtocol.quit(NativeProtocol.java:1312)
    at com.mysql.cj.NativeSession.quit(NativeSession.java:182)
    at com.mysql.cj.jdbc.ConnectionImpl.realClose(ConnectionImpl.java:1750)
    at com.mysql.cj.jdbc.ConnectionImpl.close(ConnectionImpl.java:720)
    at com.zaxxer.hikari.pool.PoolBase.quietlyCloseConnection(PoolBase.java:135)
    at com.zaxxer.hikari.pool.HikariPool.lambda$closeConnection$1(HikariPool.java:441)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)

** END NESTED EXCEPTION **

Java 代码:

 @SpringBootApplication
public class JdbcTest1Application implements CommandLineRunner {
    private static final Logger log = LoggerFactory.getLogger(JdbcTest1Application.class);

    @Autowired
    JdbcTemplate jdbcTemplate;

    public static void main(String[] args) {
        SpringApplication.run(JdbcTest1Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        log.info("Creating tables");

        jdbcTemplate.execute("DROP TABLE IF EXISTS employees");
        jdbcTemplate.execute("CREATE TABLE employees (emp_id int, name varchar(100), role varchar(100), status varchar(100))");

        log.info("Inserting Baggins Hopkins");
        int rowsAffected = jdbcTemplate.update("INSERT INTO EMPLOYEE(EMP_ID, NAME, ROLE, STATUS)"
                + " VALUES(1,'Baggins Hopkins','thief','WORKING')");
        log.info("rows affected: "+ Integer.toString(rowsAffected));
        log.info("Querying for employee");
        String sql = "SELECT emp_id,name,role,status FROM employees";
        List<Employee> employees = jdbcTemplate.query(sql,(rs, rowNum)->
        new Employee(rs.getInt("emp_id"), rs.getString("name"),
                rs.getString("role"),Status.valueOf(rs.getString("status"))));
        log.info("Part A:");
        employees.forEach(employee -> {log.info(employee.toString());
            log.info("part a");});

    }
}

另外为了以防万一,我从 application.properties 粘贴了这段代码:

 spring.datasource.url=jdbc:mysql://localhost:3306/employee_database
spring.datasource.username=employee
spring.datasource.password=employee
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

原文由 Dup Park 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 641
2 个回答

为了解决这个问题,我花了大约三天时间。

(编辑:这是测试的解决方法,实际上不是解决方案。)

起初,我从尝试为 mysql 配置我自己的 SSL 开始解决问题,为此我花了好几个小时。过了太多时间,直到我意识到配置它必须与 Cmake 和 C++ 有关,这让我放弃了。这非常令人沮丧。但是我并没有放弃,并尝试通过一种尚未找到的方法完全禁用 SSL。我最终确实找到了方法。这里是:

  1. 您必须使用 MySQL 的旧密码。旧密码是 MySQL 在 5.7x 版本中验证事物的方式。

再次打开 MySQL 安装程序,并重新配置 MySQL 服务器设置。当你到达那里时,你会看到这个屏幕:

您应该到达的屏幕

到达重新配置的最后阶段时,您可能会遇到一些错误:

我在最后阶段遇到了问题,我不知道如何解决,所以我完全卸载了 MySQL。我用窗户。我从 Program Files 中删除了 MySQL 项目根目录以卸载 MySQL。我还删除了保存在 Program Data(C 驱动器中的隐藏文件夹)中的数据库,因为我想重新开始(警告:这将删除您以前保存的所有数据!)。从控制面板卸载 MySQL 可能不足以从您的计算机中完全清除 MySQL。

  1. 删除 C:\ProgramData\MySQL\MySQL Server 8.0\Data 中的所有 *.pem 文件。 (或将其移至其他地方,这就是我所做的)

您可能在 C 驱动器中看不到 ProgramData。那是因为它是一个隐藏文件夹。为了查看隐藏文件夹:

在控制面板中搜索文件夹选项。

去查看。

在“高级设置”和“隐藏文件和文件夹”下,单击“显示隐藏文件、文件夹和驱动器”。

  1. 转到 C:\ProgramData\MySQL\MySQL Server 8.0 并打开 my.cnf(或 my.ini)。在 [mysqld] 之后添加以下行:

ssl=0

然后保存。它现在应该可以工作了。

参考:

  1. https://community.atlassian.com/t5/Confluence-questions/MySQL-Public-Key-Retrieval-is-not-allowed/qaq-p/778956
  2. https://scalegrid.io/blog/configuring-and-managing-ssl-on-your-mysql-server/

原文由 Dup Park 发布,翻译遵循 CC BY-SA 4.0 许可协议

与数据库的 SSL 连接失败,请尝试将您的数据源 URL 更改为:

 spring.datasource.url=jdbc:mysql://localhost:3306/employee_database?useSSL=false

原文由 Carrier Pigeon Protocol 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题