JavaのModule導入でGsonパースエラー
プロジェクトをJava8からJava17へLTS移行するにあたり、対処を迫られた事象の解決備忘録です
やっていたこと
Java8で構築していたプロジェクトを、Java17へ移行していました。 当該プロジェクトはMavenで構成していましたが、今回の事象は特に関係なく発生すると思われ、また対処も共通です。
either increase its visibility or write a custom TypeAdapter for its declaring type.
ビルドエラーの解消と、依存先ライブラリのバージョン更新を一通り終え、jUnitテストを流した時、
GsonのテストケースがFailed
となりました。
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.044 s <<< FAILURE! - in pro.eng.yui.myproj.pkj.sub.ParseTest [ERROR] pro.eng.yui.myproj.pkj.sub.ParseTest.fromJson Time elapsed: 0.039 s <<< ERROR! com.google.gson.JsonIOException: Failed making field 'pro.eng.yui.myproj.pkj.def.MyDataCls#dataField' accessible; either increase its visibility or write a custom TypeAdapter for its declaring type. at com.google.gson@2.10.1/com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:38) at com.google.gson@2.10.1/com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:286) at com.google.gson@2.10.1/com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130) at com.google.gson@2.10.1/com.google.gson.Gson.getAdapter(Gson.java:556) at com.google.gson@2.10.1/com.google.gson.Gson.fromJson(Gson.java:1226) at com.google.gson@2.10.1/com.google.gson.Gson.fromJson(Gson.java:1137) at com.google.gson@2.10.1/com.google.gson.Gson.fromJson(Gson.java:1047) at com.google.gson@2.10.1/com.google.gson.Gson.fromJson(Gson.java:1014) at MyProject@1.2/pro.eng.yui.myproj.pkj.utils.JsonUtil.getObjectFromJsonStr(JsonUtil.java:26) at MyProject@1.2/pro.eng.yui.myproj.pkj.sub.ParseTest.fromJson(ParseTest.java:22)
エラー内容を和訳すると、変換しようとしたクラスMyDataCls内のprivateフィールドdataFieldを読み出し可能にできませんでした。
可視度をpublicに引き上げるか、独自のTypeAdapterを定義してください
と言われています。
対策
Java9で導入されたModule
を明確化するために導入したmodule-info.java
への追記で、本エラーは対策できます。
Gson変換の対象でprivateフィールドを持つクラスが格納されているパッケージを、ひとつひとつopens
指定により、
Gsonモジュールからのreflection-accessを明示的に認めます。
Module化によってリフレクションが阻害されるという副次効果と、その対策という形になります
つれづれ
に公開した技術記事「jUnitでprivateメソッドをテストする」が、
実はこのサイト内で最多アクセスを誇る記事となっています。おかげさまでちょっとやる気が出て、同記事を英語翻訳したりもしています。(Test the PRIVATE method with jUnit)
Javaエンジニアの皆様の手助けになっていること、嬉しく思いながらGoogleAnalyticsを眺めています
謝辞・参考サイト
本記事の対応に際して参照したサイトを以下に掲げ、感謝を申し上げます
- 【Java】モジュール(Qiita@suema0331) :モジュールという概念に対する網羅的な資料として読ませていただきました。特に節「privateメソッドをopenにする」の さりげない1文が今回の解決のカギとなりました