2023/Oct/26 集まれKotlin好き!Kotlin愛好会 vol.47 で発表したものです。
JavaとGroovyで書かれたGradleプラグインをKotlinで書き直した話2023/Oct/26 集まれKotlin好き!Kotlin愛好会 vol.47Kengo TODA
View Slide
#LOVE_KOTLIN自己紹介フリーソフトウェア開発出身。OSSエンジニアやBtoB研究開発を経て、現在は医療機関向けにウェブサービスを提供する株式会社ヘンリーでSREやCorporateEngineerを担当。元SpotBugsの中の人。ChatGPTと一緒に数学書とか論文とかを読むのが最近のマイブーム。https://twitter.com/Kengo_TODAhttps://github.com/KengoTODA2
#LOVE_KOTLIN今日話すことJavaとGroovyで書いてあった spotbugs-gradle-plugin をKotlinで書き直してRC版リリースまで漕ぎつけたので、所感を共有します!3
#LOVE_KOTLINAgenda1. JavaとGroovyで書いて課題だと感じていたこと2. Kotlinの流れがきた!3. 書き換えプロセスの体験4. Kotlinで書いて良かったところ4
#LOVE_KOTLINJavaとGroovyで書いて課題だと感じていたこと- null-safetyがない、アノテーションでの補完は漏れが生じる- Groovyにtype-safety がない、IDEによる補完が効かないことがある- Gradleの文書がKotlinとGroovyを前提にしていて、Javaで書きにくい- 周りにGroovyを書いているひとがいなくなった- 昔はJenkinsfileでけっこう書かれていた( 2016年〜)- GradleのGroovy対応がv3に留まっている- 2022年からv4を検証してるけどGradle 8.0から9.0に対応を延期したので優先度高くなさそう5
#LOVE_KOTLINKotlinの流れがきた!- 2022年、自分がサーバサイドKotlinを書いてる企業に転職した- 周りにKotlinを書いているひとが多い環境になった- 2023年、GradleがKotlinをDSLの標準言語にした- 以前「Java開発者向けのKotlin Gradleビルドスクリプト入門 」を話したのでご参考まで- Gradleが提供するドキュメントも多い- 何なら公式プラグインも Kotlinで書かれていたりする- Kotlinなら型安全、null安全、強力なIDEの支援などが一気に解決される6
#LOVE_KOTLINJavaからの書き換え簡単だったので語るべきところがない- IntelliJ IDEAがJava→Kotlinの変換をだいたいやってくれる- IntelliJ IDEAがKotlinらしい書き方のサジェストもしてくれる- だいたいIntelliJ IDEAに任せておけば間違いない- フォーマットもSpotless(ktlint)にお任せ7
#LOVE_KOTLINGroovyからの書き換え面倒だったところ- IntelliJ IDEAが変換をやってくれないので自分でやる- コンストラクタ、メソッド、フィールドなど細かいところで書き方が違う良かったところ- lateinit相当のフィールドの存在に気づけた- コンストラクタでfinalではないメソッドを呼び出していたことに気づけた8
#LOVE_KOTLIN難しかったところ● functional testをSpockからKotestに切り替えたかったが、テストが起動しなかったので諦めた9
workerExecutor.submit(SpotBugsRunner.class, config -> {// getFirstEnabled() がnullableconfig.params(spec,getIgnoreFailures(),reports.getFirstEnabled().getDestination());事例Gradleプラグインにおけるnull-safetyの必要性「解析レポート出力先」をファイルパスと形式( txt,xml, html, ...)をセットで設定できる仕様だった。レポートがひとつも設定されていない場合に NPEを投げてしまった。対象メソッドには @Nullableアノテーションがついていたが、リリースされるまでこの問題に気づけなかった。https://github.com/spotbugs/spotbugs-gradle-plugin/issues/6810
#LOVE_KOTLINKotlinで書いて良かったところscope functionで初期化コードを意味ある単位でまとめて書ける11var extension = project.extensions.create(“extensionName”, MyExtension.class).apply {prop.convention(true)another.convention(“default”)}
private FileCollection classes;void setClasses(FileCollection fileCollection) {this.classes = fileCollection}FileCollection getClasses() {if (classes == null) {if (getClassDirs() == null) {throw new InvalidUserDataException("The classDirs property is not set")}return getClassDirs().asFileTree.filter({ File file ->file.name.endsWith(".class")})} else {return classes}}Kotlinで書いて良かったところフィールドの記述が短くできた12var classes: FileCollection? = nullget() {return field?: (classDirs.asFileTree.filter {it.name.endsWith(".class")})}
#LOVE_KOTLINご清聴ありがとうございましたJavaもまだ使ってるよ!という方は、今回紹介したspotbugs-gradle-pluginのv6を試してほしいですm (_ _)m13
#LOVE_KOTLIN補足 なぜJavaとGroovyを混在させていたか● もともとはJavaだけだった● 公式のプラグイン実装の書き方がGroovyで説明されていてJavaだと書きにくいことがあった● Extension周りはGroovyで書いたほうがコードも短くなることがわかった○ Javaだとアクセッサの嵐になる● でもGroovyはIDEの対応が微妙で全部書き換える気になれなかった14
#LOVE_KOTLIN補足 ファイルサイズの変化Java/Groovy (5.2.1): 圧縮後 85 KiBKotlin (6.0.0-rc.2): 圧縮後 115KiBソースコードの数はExtension用コード1つしか増えていないが、コンパイル後のclassファイルが37から69に増えている。GroovyでもClosureごとにclassファイルを作っていたが、KotlinになってLambdaがより増えた。15