小编典典

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

spring-boot

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

我创建了一个简单的Employee模型,并且试图在main()所在的同一类上执行一些数据库代码。该模型和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 Command Line Client上查询时,它返回了一个空集:

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

我不明白为什么 什么都没有插入到数据库中时,行会受到影响

stacktrace和日志:(下面粘贴的stacktrace实际上会重复多次,但是为了简洁起见,我将其切除。)

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

阅读 620

收藏
2020-05-30

共1个答案

小编典典

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

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

最初,我开始尝试通过为mysql配置我自己的SSL来解决问题,并且在此上花费了很多时间。直到我意识到配置它与Cmake和C
++有关,已经花费了太多时间,这使我放弃了。真令人沮丧。但是,我没有放弃,而是尝试通过一种尚未发现的方法完全禁用SSL。我最终找到了方法。这里是:

  1. 您必须为MySQL使用旧密码。遗留密码是MySQL在5.7x版中对事物进行身份验证的方式。

再次打开MySQL安装程序,然后重新配置MySQL Server设置。当您到达那里时,将看到以下屏幕:

您应该进入的屏幕

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

在最后阶段我遇到了问题,我不知道如何解决,所以我完全卸载了MySQL。我用窗户。我从“程序文件”中删除了MySQL项目的根目录,以卸载MySQL。我还删除了保存在程序数据(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/
2020-05-30