私は現在、JDBCの実装とSpring Boot webappでのデータベースの使用についてより多くを学んでおり、投稿の最後に書かれた以下のスタックトレースに遭遇しました。
シンプルなEmployeeモデルを作成し、main()が存在する同じクラスでデータベースコードを実行しようとしています。モデルとメインクラスは、この中に存在する2つのJavaファイルのみですプロジェクト全体。私は、CommandLineRunnerインターフェイスからのコードをオーバーライドする次のrun()コードを実装しようとしていますが、log.info( "Part A:"の後に来るはずのログを取得しません。 ):
log.info("Part A:")
employees.forEach(employee -> {log.info(employee.toString());
log.info("part a");});
-私が気づいたこと:
スタックトレースが開始される前のログの最後の行は、「main」ではなく「Thread-1」に由来することに気付きました。これは、メイン以外の場所からのスレッドがエラーを検出し、正常に閉じる前に接続を閉じたことを意味すると思います。
また、「peer's close_notify」の前に閉じられたHikariPoolであるため、これは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
データベースに何も挿入されていないときに行が影響を受けたの理由がわかりません。
スタックトレースとログ:(以下に貼り付けられたスタックトレースは、実際にはさらに数回繰り返されますが、簡潔にするために切り取りました。)
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
この問題を解決するには、約3日かかりました。
(編集:これはテストのための回避策であり、実際の解決策ではありません。)
最初に、mysql用に独自のSSLを設定しようとすることで問題の解決を開始し、それにかなりの時間を費やしました。設定にCmakeとC++が関係していることに気付くまで時間がかかりすぎたため、あきらめました。とてもイライラしました。しかし、私はあきらめず、見つかっていない方法でSSLを完全に無効にしようとしました。そして、私は最終的にその方法を見つけました。ここにあります:
MySQLインストーラーを再度開き、MySQLサーバー設定を再構成します。そこに着くと、この画面が表示されます:
再構成の最終段階に達すると、エラーが発生する場合があります。
最終段階で問題が発生したため、修正方法がわからなかったため、MySQLを完全にアンインストールしました。私は窓を使用します。 MySQLをアンインストールするために、Program FilesからMySQLプロジェクトのルートディレクトリを削除しました。また、プログラムデータ(Cドライブの隠しフォルダー)に保存されたデータベースも削除しました(警告:これにより、以前に保存したすべてのデータが削除されます!)。コントロールパネルからMySQLをアンインストールしても、コンピューターからMySQLを完全に消去するには不十分な場合があります。
CドライブにProgramDataが表示されない場合があります。それは隠しフォルダーだからです。隠しフォルダーを表示するには:
コントロールパネルでフォルダオプションを検索します。
ビューに移動します。
[詳細設定]および[非表示のファイルとフォルダー]で、[非表示のファイル、フォルダー、およびドライブを表示]をクリックします。
ssl = 0
次に保存します。これで動作するはずです。
編集:更新クエリのSQL構文が間違っていることに気付きました。間違ったテーブルに挿入していました。 SSLExceptionの問題を修正したかどうかに関係なく、データベースへの挿入はまだ機能していると思います。 (私はよくわかりません...)
参照:
データベースへのSSL接続に失敗しています。データソースURLを次のように変更してみてください。
spring.datasource.url=jdbc:mysql://localhost:3306/employee_database?useSSL=false
警告は、Java 11およびSSLが有効なMySQLドライバーのバグのように見えます: https://bugs.mysql.com/bug.php?id=9359
ドライバーのために暗号化を無効にするwarningは悪い考えです。
挿入の問題は、従来のトランザクションの問題のように見えますが、SSL警告に関連しているとは思えません。
私も同じ問題に直面しました。スタックトレースを見ると、何をすべきかが明確に述べられています-
Sat Mar 16 09:00:01 IST 2019 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'.
You need either to explicitly disable SSL by setting **useSSL=false**, or set **useSSL=true** and provide truststore for server certificate verification.
データソースのURLを変更してSSLを無効にした後、問題を解決しました-
spring.datasource.url=jdbc:mysql://localhost:3306/security?useSSL=false
この問題が発生したため、Tomcatをバージョン9.0.12から9.0.16に更新して誤って解決するまで、 Carrier Pigeon Protocolのソリューション を使用することにしました。