1年のアウトプットを振り返る

この振り返りも5年目となりましたがやっていきます。

wrongwrong163377.hatenablog.com

OSS関連

jackson-module-kotlinのメンテナになった

今年最大の変化はjackson-module-kotlinのメンテナになったことです。

jackson-module-kotlinのメンテナは、2022年中ほぼ不在でした。
また、以前のメンテナも新機能の追加やバグの修正、性能改善などには積極的でなく、実質数年開発が止まっている状況でした。
そんな中、以前からの貢献もあってJackson全体のメンテナをされている方からお誘いを頂いたため、思い切って手を挙げることにしました。

jackson-module-kotlinへの貢献

2023年の年始からメンテナンス作業を始め、年内で既に30程度の変更をマージしています(今現在も作業中です)。
この他にも、テストの修正やイシューの整理(合計150件位closeしました)、databind側の数件の修正やイシュー報告といった点で貢献できました。

github.com

正直な所、最初はイシュー対応など英語でのやり取りは難しいだろうと考えていましたが、DeepLさえあれば割となんとかなりました。
ただ、英訳含め対応には非常に多くの時間がかかってしまう上、直接jackson-module-kotlinに不備があるようなケースはかなり少なかったため、正直今でもイシュー対応はやりたくない作業になっています。

jackson-module-kogeraの開発

jackson-module-kotlinに関する実験的な実装を行うための場として、jackson-module-kogeraというプロジェクトも始めました。

github.com

kotlinx-metadata-jvmへの置換やデシリアライズの大幅高速化、value class対応と、様々な難しい要素を実現できたため、このプロジェクトは割と自慢できる仕上がりになっています。
客観的にも、人生初の100スターを集めたプロジェクトとなりました。
以前やっていたプロジェクトではここまで到達できなかったため、非常に嬉しかったです。

ベンチマークプロジェクトの方も色々工夫でき、充実した開発ライフを過ごせました。

github.com

その他OSSへの貢献

今年はjackson-module-kotlin関連ばっかりだったので、それ以外の貢献はあまり有りませんでした。
kotlin-reflectの軽微なバグ修正と、mockkの軽微なパフォーマンス改善位です。

ブログ・外部登壇

ブログ

がっつりOSS活動に振り切った1年でしたが、一応30本は書いていたようです。
正直、業務的に何か新しい発見をすることは減ってしまいましたし、OSSならブログ書いてるよりPR出す方に行ってしまいがちなので、中々書けない感が有ります。

外部登壇

今年は前半3回ほど登壇していました。
来年も1回位はどこかで登壇したいですね(といってもまずはOSSの開発優先になりそうですが)。

終わりに

今年はアウトプット面でとても充実した1年だったと思います。

特にjackson-module-kotlin関係では様々な改善を行うことができました。
自分の入れた改善を全世界の人間が参照しているというのはとても面白い感覚があります。
間違いなく、自分のアウトプットが発揮した価値は過去最高を更新しました。

jackson-module-kotlinへの関わり方に関しては、来年リリース予定の2.17でいよいよ数年越しのvalue class対応を入れられそうなこともあって、まだまだモチベーションは有ります。
ただ、余暇の大半がjackson-module-kotlinに消えてしまったのはちょっと考えものでした。
そのため、2.18辺りを目処にjackson-module-kotlinへの関与は減らすつもりです。

OSSに関わりたい欲の解消やジム通いの再開など、来年も充実させていければと思います。

【Spring WebFlux】Bean初期化処理でblockすると、lazy-initが有効な場合に実行時エラーになる

以下の追記部で紹介した話です。

qiita.com

本文

lazy-initが無効な場合、Bean初期化処理中であればblockしても特に問題は起きません。
このため、Bean初期化時のwarmup目的でblockすることもできます。

一方、lazy-initが有効な場合、アクセス時のコンテキストでblockが呼び出されてしまうため、それによるエラーが発生します。

そもそもlazy-initが有効であれば、リクエストを待たせてまでwarmupする意味は無いため、プロパティを見て処理をスキップすることをおすすめします。

KotlinlangのSlackでThank Youが明るくなった話

qiita.com

この記事はSwift/Kotlin愛好会 Advent Calendar 2023の3日目の記事になりました。


Kotlin言語には、JetBrainsの管理する公式Slackワークスペースが有ります。

kotlinlang.slack.com

このワークスペースでは、現在:thank-you-color:として以下のスタンプが使われています。

このスタンプの導入にまつわるJetBrainsさんの神対応について書きます。

以前のスタンプの問題点

以前のスタンプを再現すると、以下のようなものでした。

改行無しだったため見にくく、黒一色・透過有りだったせいで、ダークモードにすると更に読みにくくなっていました。
悪いことに、当時は:not-kotlin:という割と否定的な意味のスタンプも同様のフォーマットで存在しており、両者を見分けにくいという問題も有りました。

変更のきっかけ

この辺りのことが気になった自分は、変更を提案してみました。

slack-chats.kotlinlang.org

すると、何と約1日ほどでKotlinのテーマカラーを意識したスタンプを用意してもらうことができました。

現在古いスタンプは削除され、コミュニティの全員が感謝を鮮やかに示すことが出来るようになっています。

終わりに

KotlinlangSlackJetBrainsさんに神対応して頂いた話でした。

KotlinlangSlackには日々Kotlinの様々な話が流れており、様々な話題を読むことが出来るので、是非参加してみて下さい。
また、Kotlinlang本家のjapaneseチャンネルや、kotlinlang-jpSwift/Kotlin愛好会など、日本語コミュニティもお勧めです!

【Gradle】Windows環境でorg.gradle.api.InvalidUserDataException: Source directory ... is not a directory.になる問題への対処

一度ローカルからプロジェクトを消した上で、以下のようにcloneし直すことで解決します。

git clone -c core.symlinks=true https://github.com/<your_name_here>/<your_repository_here>

参考にさせて頂いたサイト

github.com

github.com

文脈

自分はokioをビルドしようとしてこの問題に当たりました。

github.com

KotlinプロジェクトでGradle 7.6.2 -> Gradle 8.3移行をした時の作業メモ

自分が取り組んでいるKotlinOSSプロジェクトにて、Gradle 7.6.2 -> Gradle 8.3の移行をやった際にハマったことのメモです。

github.com

きっかけ

このプロジェクトには、GitHub ActionsKotlin x Javaのバージョンを組み合わせ毎の挙動を確認するグリッドテストが有ります。

このテストにK2コンパイラを使うパターンも追加しようとした所、関係の無いはずのケースが失敗するようになりました。
エラーログを確認した所キャッシュ起因に見えたので、キャッシュを全消ししてやり直した所、当該箇所は直ったものの、今度はJava 20を使うケース全てが失敗するようになりました。

エラーログには以下のように表示されていました。

* What went wrong:
Could not open cp_init generic class cache for initialization script '/home/runner/.gradle/init.d/gradle-build-action.build-result-capture.init.gradle' (/home/runner/.gradle/caches/7.6.2/scripts/9b672n24db1z169ivld6c2v82).
> BUG! exception in phase 'semantic analysis' in source unit '_BuildScript_' Unsupported class file major version 64

対応

Gradleのアップデート

エラーログを検索したところ、Javaバージョンの不整合という情報が引っかかったため、Gradleバージョンの移行を決断しました。

discuss.gradle.org

バージョンアップは以下の2コマンドを実行することで行いました。

./gradlew wrapper --gradle-version=8.3
./gradlew wrapper

build.gradle.ktsの修正

buildDir -> layout.buildDirectory

プロジェクト内でbuildDirを参照している部分が有りましたが、当該プロパティは非推奨化していたので、以下のように変更を行いました。

- val generatedSrcPath = "$buildDir/generated/kotlin"
+ val generatedSrcPath = "${layout.buildDirectory.get()}/generated/kotlin"

compileTestKotlinへのjvmTarget指定

変更後、Kotlin 1.8以降 & Java 11以上の場合compileTestKotlinが落ちるようになりました。
エラーログは以下のようになっておりました。

* What went wrong:
Execution failed for task ':compileTestKotlin'.
> 'compileTestJava' task (current target is 1.8) and 'compileTestKotlin' task (current target is 11) jvm target compatibility should be set to the same Java version.
  Consider using JVM toolchain: https://kotl.in/gradle/jvm/toolchain

当該プロジェクトではjvmTargetJava 8を指定していますが、どうもKotlin 1.8以降の場合compileTestKotlin側にも同様の指定が無ければ不整合扱いになるようです。
以下の記述を追記して対応しました(もしかするとjvmTargetを消す方が望ましいかもしれません)。

tasks {
    /* 略 */
+   compileTestKotlin {
+       kotlinOptions.jvmTarget = "1.8"
+   }
    /* 略 */
}

感想

最初のバグは何だったのか、何故キャッシュ削除前はJava 20のテストが成功していたのか、深い謎が残りましたが、一旦K2のテストも成功しているので気にしないことにします……。

【Gradle】Windows環境でjmh-gradle-pluginの出力ファイルをUTF-8にする

TL;DR

  • gradle.propertiesorg.gradle.jvmargs-Dfile.encoding=UTF-8を指定するのが良さそう
  • jmh-gradle-pluginに指定する方法は無さそう

背景

jmh-gradle-plugin(me.champeau.gradle.jmh)は、環境に合わせた文字コードhumanOutputFileを出力します。
このため、何も指定しない場合Windows環境ではShift-JISで出力されます。

ここで、IntelijからhumanOutputFileを開く場合、この挙動によって±が文字化けし、コピペも難しくなる問題が有ります。

対処

C:\Users\${ユーザー名}\.gradlegradle.propertiesファイルを用意し、以下の内容を追記しました。

org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

重要なのは-Dfile.encoding=UTF-8オプションで、これによって出力の文字コードUTF-8になります。

jmh-gradle-plugin側のオプションも確認しましたが、出力ファイルの文字コードを変更するようなオプションは無いようでした。

補足: 指定内容について

この指定内容はGradle公式ドキュメントの以下の記述からコピーしたものです。

docs.gradle.org

この指定では、デフォルトより多くメモリを消費します。
自分のローカルではメモリ容量に余裕が有ったため、パフォーマンス向上を目的にこのオプションを指定しています。

【Flyway】特定イベント後に実行するSQLファイルを設定する

やりたいこと

flywayによるマイグレーションでテーブルが追加された場合に、共通のトリガー設定SQLを動かすようなことをします。
生で書いてしまった場合1度しか実行されないため、これを実現するには工夫が必要です。

やり方

Callback機能を利用することで実現できます。
自分の場合マイグレーション成功時にのみ実行したかったため、afterMigrate__${識別用の名前}.sqlを作成・配置しました。

その他どのようなCallbackが存在するかは公式資料をご覧下さい。

documentation.red-gate.com