Slide 1

Slide 1 text

jackson-module-kotlin を読もう! 1

Slide 2

Slide 2 text

始める前に この発表では解説に jackson-module-kotlin リポジトリのコードを利用します リポジトリ & 使用するブランチのURLは下記の通りです https://github.com/FasterXML/jackson-module-kotlin/tree/2.13 2

Slide 3

Slide 3 text

自己紹介 宮田 木織 株式会社justInCaseTechnorogiesバックエンドエンジニア アウトプットしているアカウント Qiita: @wrongwrong GitHub: k163377 OSS活動 去年から jackson-module-kotlin へしばしばコントリビュートしています 2021年下半期のコミット数世界一でした 最近は kotlin-reflect の value class 絡みのバグ修正にも携わりました 3

Slide 4

Slide 4 text

Jackson /jackson-module-kotlin とは Jackson は、 Java 向けでは世界で最も使われている JSON ライブラリの一つ 外部モジュールを使えば CSV や XML といったフォーマットも処理可能 jackson-module-kotlin は、 Jackson を Kotlin で利用するためのモジュール 以下のような機能を提供している コンストラクタ呼び出しでのデシリアライズ Kotlin 固有の型に関するシリアライズ/デシリアライズ Jackson を Kotlin から扱いやすくする関数類 特に Kotlin で SpringBoot を使う場合かなり利用機会がある 4

Slide 5

Slide 5 text

所で…… jackson-module-kotlin のコードを読んだことは有りますか? ライブラリを使いこなすには、読んでみるのが効果的です 設定可能な項目の把握 挙動をカスタムする際に利用できそうな機能の把握 一方、ライブラリのコードを事前知識や目標無しで読み始めるのは結構大変です この発表では、ざっくり jackson-module-kotlin を読んでみたい方向けに、何がどこ に書かれているかや、具体的な処理内容について軽く解説します 5

Slide 6

Slide 6 text

この発表で紹介する内容 KotlinModule.kt / KotlinFeature.kt kotlin-module の持っている機能や設定項目を俯瞰できる KotlinNamesAnnotationIntrospector.kt kotlin-module の重要な機能を多く実装している (コントリビュートしてみたい方向けのおまけ) kotlin-module のビルド・テスト方法について 自分がどのようにコードを読んでいるか すぐ直せそうな問題 6

Slide 7

Slide 7 text

発表形式について ここからは、実際のコードを中心に、スライドは補助資料として発表していきます。 7

Slide 8

Slide 8 text

KotlinModule.kt 受け取った設定に基づき Jackson ( ObjectMapper )に様々な機能を登録するクラス kotlin-module にどのような設定ができるか/ Jackson のどのような機能を利用して いるか俯瞰できる ここでは設定可能な項目や登録されている機能の一部を紹介する 8

Slide 9

Slide 9 text

KotlinModule.kt KotlinFeature.kt KotlinModule.Builder への設定項目 設定可能な項目の例 値が null の場合にデフォルト値を利用する デシリアライズ時に Collection 要素の nullability を厳密にチェックする KotlinModule.Builder 設定を登録した上で KotlinModule を生成するビルダー 設定可能な項目の例 KotlinFeature の有効/無効化 リフレクション処理のキャッシュ量の上限値 9

Slide 10

Slide 10 text

KotlinModule.kt setupModule 受け取った設定に基づき、各機能のインスタンス生成・登録を行う関数 登録されている機能の例 デシリアライズ時のパラメータ読み出し/関数呼び出しの制御関連 ( KotlinInstantiators ) Kotlin 固有の型に関するシリアライズ・デシリアライズ設定関連 ( ~Deserializers / ~Serializers ) ObjectMapper に登録している機能を俯瞰できる 10

Slide 11

Slide 11 text

KotlinNamesAnnotationIntrospector.kt AnnotationIntrospector は様々なカスタム挙動を実装するためのクラス アノテーションに関係なく、シリアライズ・デシリアライズ問わず、多くの挙動を カスタムできる kotlin-module でも多くの重要な機能を実装している ここでは実装されている機能の一部を紹介する 11

Slide 12

Slide 12 text

KotlinNamesAnnotationIntrospector.kt Kotlin 上のis~ というプロパティのシリアライズ結果を自然にする処理 Jackson のデフォルト挙動では、 isFoo() という getter は foo プロパティになる これは Kotlin から見ると不自然な挙動 findRenameByField getter から作られたプロパティ名をフィールド名から補正するための関数 is から始まるプロパティ名だった場合にそれが消えないようにしている 12

Slide 13

Slide 13 text

KotlinNamesAnnotationIntrospector.kt 自然にコンストラクタを呼び出してデシリアライズするための処理 Jackson 単体では Kotlin 上のプライマリコンストラクタ認識してデシリアライズに用いる ようなことはできないため、カスタム挙動が実装されている。 hasCreatorAnnotation 主にプライマリコンストラクタをデシリアライズに利用するための関数 JsonCreator アノテーションが付与されていることにしている findKotlinParameterName Kotlin 上の引数名を Jackson から利用するため処理 13

Slide 14

Slide 14 text

KotlinNamesAnnotationIntrospector.kt 補足 KotlinAnnotationIntrospector.kt も AnnotationIntrospector を継承している 14

Slide 15

Slide 15 text

まとめ この発表では、ざっくり jackson-module-kotlin を読んでみたい方向けに幾つかのコ ードを解説しました jackson-module-kotlin のコードを読んでみるのは、 Jackson を使いこなす上で非 常に役に立つと思います 紹介しきれなかったコードも多くあるので是非1度読んでみて下さい! 特に役立ちそう: Extensions.kt コントリビュートしてみたい方も是非! 15

Slide 16

Slide 16 text

We are hiring! justInCaseTechnologiesでは保険APIサーバーを開発するバックエンドエンジニアを募集 しています 技術スタック: Kotlin / Spring Webflux / AWS 「助けられ、助ける喜びを、全ての人へ。」をテーマに、保険業務の効率化によってみ なさんによりよい保険を届けます 詳しくはホームページから! 採用全般 エンジニア求人一覧 16

Slide 17

Slide 17 text

おまけ 17

Slide 18

Slide 18 text

jackson-module-kotlin をビルドしてテストを走らせるまで 前提 Intellij IDEA や Java ・ Maven を動かすための環境は構築済みとする リポジトリは fork ・ clone 済みとする https://github.com/FasterXML/jackson-module-kotlin Maven のコマンドは mvn ~~ で記述する 18

Slide 19

Slide 19 text

jackson-module-kotlin をビルドしてテストを走らせるまで テスト実行 mvn verify で全てのテストが実行できる Windows の場合改行コード問題で一部テストが失敗する 補足: IDEA から初回テストを実行する mvn replacer:replace を先に実行(← ここ重要!) 初回は必要なコードがローカルに生成されていないため mvn verify で実行した場合、これも自動で実行されている IDEA からテストを実行 e.g. テスト横の再生ボタンを押す 19

Slide 20

Slide 20 text

jar を生成する mvn jar:jar で、 ${ プロジェクトルート}/target 配下に jackson-module- kotlin-${ バージョン}.jar が出力される まだ公開されていない SNAPSHOT などは、ローカルで生成した jar を使って検証で きる 20

Slide 21

Slide 21 text

自分がどのようにコードを読んでいるか 1. まずそのまま読んでみる 2. その処理を消すか編集してテスト結果がどう変化するか見る 3. 地道にドキュメント漁りと挙動実験をする 21

Slide 22

Slide 22 text

すぐ直せそうな問題 OSS にコントリビュートしてみたい方向けに、軽微で簡単そうな問題を幾つか示します 以下の点にご注意ください 提示する内容は発表者の認識であるため、実際に対応する場合必ず検証すること jackson-module-kotlin に関しては、 CLA の提出が必要なこと メンテナが半分失踪中なため、レビューがいつになるか分からないこと 22

Slide 23

Slide 23 text

すぐ直せそうな問題(1) Extensions.kt fun foo(...) = Unit.apply { ... } となっている関数の = Unit.apply は 消せる KotlinDeserializers.kt type.isInterface の判定は消せる その後に class の一致を判定しているので interface 比較は無意味 KotlinFeature.kt BitSet 関連の計算が非効率 23

Slide 24

Slide 24 text

すぐ直せそうな問題(2) KotlinKeyDeserializers.kt unsigned integers 系の処理では super.deserializeKey するより目的の値に 直接パースした方が効率的 パースには StdKeyDeserializer の _parseInt のような関数を利用する KotlinModule.kt ClosedRange に対してだけ Mixin を登録する形にできる 登録されている ~Range は全て ClosedRange を継承しており、特別なプロパ ティも無い KotlinNamesAnnotationIntrospector.kt このクラスを KotlinAnnotationIntrospector にまとめてもテスト結果は変化し ないため、まとめられるかも (これは結構検証が難しいかもしれない) 24