Spring Boot 2系にバージョンアップしたらH2がエラーを吐き出したときの対処
概要
Spring Boot 1.5系からSpring Boot 2系にバージョンアップしたときにH2がエラーを吐き出したので調査しました。
ここでは調査して分かったこととエラーをどう対処したかを書きます。
問題が起きたときの各ライブラリのバージョン
ライブラリ | バージョン |
---|---|
Spring Boot | 2.1.6 |
H2 | 1.4.192 |
問題
エラーの内容は以下。
isWrapperForがサポートされていないため例外を吐いている模様。
2020-01-16 00:09:52 JDBCX: exception
org.h2.jdbc.JdbcSQLException: 機能はサポートされていません: "isWrapperFor"
Feature not supported: "isWrapperFor" [50100-192]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.message.DbException.getUnsupportedException(DbException.java:216)
at org.h2.message.TraceObject.unsupported(TraceObject.java:375)
at org.h2.jdbcx.JdbcDataSource.isWrapperFor(JdbcDataSource.java:422)
at org.springframework.boot.jdbc.DataSourceUnwrapper.safeUnwrap(DataSourceUnwrapper.java:77)
at org.springframework.boot.jdbc.DataSourceUnwrapper.unwrap(DataSourceUnwrapper.java:56)
at org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvidersConfiguration$HikariPoolDataSourceMetadataProviderConfiguration.lambda$hikariPoolDataSourceMetadataProvider$0(DataSourcePoolMetadataProvidersConfiguration.java:66)
at org.springframework.boot.jdbc.metadata.CompositeDataSourcePoolMetadataProvider.getDataSourcePoolMetadata(CompositeDataSourcePoolMetadataProvider.java:50)
...
調査
エラーログから、SpringのコードのDataSourceUnwrapper#safeUnwrapメソッドで例外が起きているようなので見てみます。
https://github.com/spring-projects/spring-boot/blob/2.1.x/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceUnwrapper.java#L77
private static <S> S safeUnwrap(Wrapper wrapper, Class<S> target) {
try {
if (wrapper.isWrapperFor(target)) {
return wrapper.unwrap(target);
}
}
catch (Exception ex) {
// Continue
}
return null;
}
isWrapperというメソッドが使われてました。isWrapperForとはメソッドのことですね。H2ではこのメソッドのサポートがないみたいです。
そしてH2のchangelogを確認してみたところ、それを裏付ける記述がありました。
PR #844: Add simple implementations of isWrapperFor() and unwrap() to JdbcDataSource
バージョン1.4.197でisWrapperForメソッドの実装がJdbcDataSourceに追加されたみたいです。どうやらSpring Boot 2.1.6ではisWrapperForメソッドありきの実装になっていますが、H2のバージョンが1.4.192のため、このメソッドがなく例外となっていたようでした。
一応Spring Boot 2.1.6はH2のどのバージョンに依存しているのか確認します。
Maven Repositoryを見ると、まずSpring Boot(Spring Boot JDBC Starter) 2.1.6がSpring JDBC 5.1.8に依存しており、そしてSpring JDBC 5.1.8がH2 1.4.199に依存しています。つまり、Spring Boot 2.1.6はH2 1.4.199に依存しているのでこれで辻褄が合いました。
ちなみに、Spring Boot 1.5系でエラーとなっていなかった理由はそもそもDataSourceUnwrapper#safeUnwrapメソッドがなく、isWrapperForメソッドが呼ばれないためでした。
解決策
H2のバージョンを1.4.199に上げました。
...
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.199</version>
</dependency>
...
これでエラーを吐き出さなくなりました。
まとめ
今回はSpring Boot 2系にバージョンアップした際のH2のエラーの原因調査と解決を行いました。
最終的な各ライブラリのバージョンは以下になります。
ライブラリ | バージョン |
---|---|
Spring Boot | 2.1.6 |
H2 | 1.4.199 |
教訓としては、フレームワークやライブラリをバージョンアップした際は依存ライブラリのバージョンと前のバージョンからの変更点をchangelogやリリースノートで確認しましょう。これでどんな変更によって挙動が変わったかどうかをある程度チェックできると思います。
maven等を利用してライブラリ管理をしている場合はMavenRepositoryを確認して依存ライブラリのバージョンをチェックできます。MavenRepositoryであればリンクを辿ってすぐに調べられます。
changelogやリリースノートも公式URLやGithubに載っていることが多いので見てみると良いと思います。
Author And Source
この問題について(Spring Boot 2系にバージョンアップしたらH2がエラーを吐き出したときの対処), 我々は、より多くの情報をここで見つけました https://qiita.com/kawakawaryuryu/items/1321600515ca3302c8e1著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .