Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレン...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
ternbusty
May 29, 2026
Programming
180
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレンドリーな Java API 設計
ternbusty
May 29, 2026
More Decks by ternbusty
See All by ternbusty
Open Source Summit North America 2026: Building a Shared, Persistent Virtual Filesystem for WebAssembly
ternbusty
1
110
CloudNative Days Winter 2025: 一週間で作る低レイヤコンテナランタイム
ternbusty
7
2.7k
JJUG CCC 2025 Fall: Virtual Thread Deep Dive
ternbusty
4
820
Server Side Kotlin Meetup vol.16: 内部動作を理解して ハイパフォーマンスなサーバサイド Kotlin アプリケーションを書こう
ternbusty
5
580
Other Decks in Programming
See All in Programming
エージェンティックRAGにAWSで入門しよう!
har1101
8
1.6k
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
280
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.1k
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
160
TAKTでAI駆動開発の品質を設計する
j5ik2o
7
1.3k
気圧・高度・GPSを記録&可視化するアプリ「Koudo」を作った話
hjmkth
1
270
Webフレームワークの ベンチマークについて
yusukebe
0
170
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
200
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
11
5.7k
dRuby over BLE
makicamel
2
340
Composerを使ったサプライチェーン攻撃の様子を眺めてみる #phpstudy
o0h
PRO
2
250
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
580
Featured
See All Featured
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
360
The Curse of the Amulet
leimatthew05
1
13k
Embracing the Ebb and Flow
colly
88
5.1k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.7k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
How STYLIGHT went responsive
nonsquared
100
6.2k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.5k
Speed Design
sergeychernyshev
33
1.8k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
250
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
140
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
Believing is Seeing
oripsolob
1
150
Transcript
© LY Corporation JSpecify で実現する Kotlin フレンドリーな Java API 設計
LINEヤフー株式会社 早坂 絢⼦
© LY Corporation 2 Ayako Hayasaka LINEヤフー株式会社 Software Engineer 2023
年度⼊社 SWAT チーム所属 Web バックエンド領域で全社横断的な技術⽀援を実施 Java ⾔語サポートチーム所属 メインは Spring Boot + Java / Kotlin 外部登壇 • JJUG CCC 2025 Fall: Virtual Thread Deep Dive • CloudNative Days Winter 2025: ⼀週間で作る 低レイヤコンテナランタイム • Open Source Summit North America 2026: Building a Shared, Persistent Virtual Filesystem for WebAssembly OSS Contribute • Google Summer of Code 2026: Tail call support in the Kotlin/Wasm backend (Kotlin Foundation, 進⾏中) © LY Corporation 2
© LY Corporation 3 LINEヤフーでの Server Side Kotlin の広がり https://techblog.lycorp.co.jp/ja/20260318b
サーバーサイド開発で使⽤している開発⾔語はどれですか? Java Kotlin
© LY Corporation LINEヤフーでの Server Side Kotlin の広がり • LINEメッセージングプラットフォーム,
LINE公式アカウント, LINE Store, LINEギフト, LINEポイント, LINEミニアプリ, Yahoo!フリマ, Yahoo!カレンダー, Yahoo!ファイナンス など多くの採⽤事例・求⼈あり • 社内の Java サポートチームでも Server Side Kotlin のサポートを開始 • Java チームで提供しているライブラリを Kotlin から使う場合の サンプルレポジトリ提供 • Java エンジニアのための Kotlin ガイド等ドキュメント整備 • Java チームで提供しているライブラリを Kotlin から利⽤しやすく する対応 4
© LY Corporation LINEヤフーでの Server Side Kotlin の広がり • LINEメッセージングプラットフォーム,
LINE公式アカウント, LINE Store, LINEギフト, LINEポイント, LINEミニアプリ, Yahoo!フリマ, Yahoo!カレンダー, Yahoo!ファイナンス など多くの採⽤事例・求⼈あり • 社内の Java サポートチームでも Server Side Kotlin のサポートを開始 • Java チームで提供しているライブラリを Kotlin から使う場合の サンプルレポジトリ提供 • Java エンジニアのための Kotlin ガイド等ドキュメント整備 • Java チームで提供しているライブラリを Kotlin から利⽤しやすく する対応 5
© LY Corporation Java と null アノテーションの⻑く泥臭い歴史 Kotlin から Java
のライブラリを利⽤する際に困ること Java ライブラリ側で必要な対応 Platform Type の検出⽅法 まとめ 01 03 02 04 05 6 Agenda
© LY Corporation 前提知識: Java における null の課題 • Java
では、すべての参照型に null が代⼊可能 • 型レベルで、nullable か否かを表現することができない • 結果として、静的解析では null の有無を判定できず、実⾏時に初めて NullPointerException (NPE) が発⽣する → どうにかして、静的解析時に参照できるような、Nullability を表現する⽅法が 欲しい! 7 Annotation を付与することで Nullability を 表現する仕組みがあればいいのでは?
© LY Corporation 歴史: null 安全アノテーションの乱⽴ • JetBrains, Spring Framework
などがそれぞれ独⾃の @Nullable or @NotNull or @NonNull アノテーションを定義 • 同じ名前だが別物、IDE で警告が出ない等の問題が顕在化 • 統⼀されたアノテーションを作ろうとした JSR-305 (javax.annotations.*) も頓挫 nullの10億ドルの過ちから未来へ Spring Boot 4とJSpecifyが描くnull安全設計 8
© LY Corporation JSpecify の登場 • 2021 年に Google が⽴ち上げ、2024
年に 1.0.0 をリリース • Broadcom (Spring プロジェクト)、JetBrains、Oracle (OpenJDK)、 Uber (NullAway) など主要なステークホルダーに⽀えられている *1 • Spring Framework 7 および Spring Boot 4 以降で採⽤ *2 • Spring Boot 4 以降では Spring の主要な API は JSpecify アノテーション付き! • コレクションの中⾝の型等にも Annotation を付与できる *1: https://jspecify.dev/about/ *2: https://spring.io/blog/2025/03/10/null-safety-in-spring-apps-with-jspecify-and-null-away List<@Nullable String> role; 9
© LY Corporation 10 ⼀⽅そのころ Kotlin は……? Kotlin から Java
のライブラリを利⽤する際に困ること 02
© LY Corporation Kotlin の null 安全性 • Java と違い、null
を許容する型 (例: String?) とそうでない型 (例: String) を 型システムレベルで明⽰しているので、静的解析でエラーにできる じゃあ、Java にあるような アノテーションがどうこう みたいな問題とは無縁だね! 11
© LY Corporation Kotlin の null 安全性 • Java と違い、null
を許容する型 (例: String?) とそうでない型 (例: String) を 型システムレベルで明⽰しているので、静的解析でエラーにできる じゃあ、Java にあるような アノテーションがどうこう みたいな問題とは無縁だね! コトはそう単純ではない! 12
© LY Corporation Platform Type とは? • 問題は、Kotlin から Java
の関数を呼び出すときに発⽣する public String find() { return System.getProperty("x"); } val s = api.find() s.length Java Kotlin Kotlin からすると、find の返り値が null かそうでないかわからず、null かどうか 不明な Platform Type として解釈される (s の型は String!) 13 null かどうかわからないので null チェックも強制されない もし s の値が null だったらここで NPE が発⽣してしまう
© LY Corporation IDE での表⽰を確認 14 ホバーすると String! であることはわかるが 特に
IDE で警告はなく、 コンパイルエラーも出ない Java Kotlin 実⾏時 実⾏時には NPE が⽣じる
© LY Corporation Annotation をつけてみると? 15 • JSpecify の @Nullable
annotation がついているとどうなる? public @Nullable String find() { return System.getProperty("x"); } val s = api.find() s.length Java Kotlin アノテーションのおかげで s の型は String? になる コンパイルエラーになり、 null ハンドリングが強制される
© LY Corporation IDE での表⽰を確認 16 @Nullable アノテーション付与済み Java Kotlin
コンパイルエラーになり、 null ハンドリングが強制される
© LY Corporation Kotlin から解釈できる annotation 17 • Kotlin 1.1.50
でコンパイルオプション -Xjsr305=strict が登場 *1 • これを指定すると、@Nullable のついた変数の null ハンドリングが強制される (コンパイルエラーになる) • Kotlin 1.5.20 からは JSpecify のサポート開始 *2 • 2.0.20 からは JSpecify の全てのアノテーションを正しく解釈できるようになった • 当初はデフォルトでは warn 扱いだったが、Kotlin 2.1 からはエラー扱いに • コンパイラオプション -Xnullability-annotations で挙動を変更できる *3 • 現在解釈できる annotation は上記含む 9 種類 *4 *1: https://blog.jetbrains.com/kotlin/2017/09/kotlin-1-1-50-is-out/ *2: https://kotlinlang.org/docs/whatsnew1520.html#support-for-jspecify-nullness-annotations *3: https://jspecify.dev/docs/whether/#kotlin *4: https://kotlinlang.org/docs/java-interop.html#nullability-annotations
© LY Corporation Spring Boot 4 時代の nullability annotation 18
• Spring Boot 3.x は 2026 年 6 ⽉に EOL なので Spring Boot 4 を前提とすると…… • Spring Boot 4 では *1 • Spring の API に JSpecify Annotation 付与済み • Kotlin のベースラインは 2.1 に引き上げ • JSR-305 は事実上の休⽌状態 *2, Spring Framework の annotation も deprecated *3 *1: https://spring.io/blog/2025/12/18/next-level-kotlin-support-in-spring-boot-4 *2:https://jcp.org/en/jsr/detail?id=305 *3: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0.0-M2-Release-Notes 新たに nullability アノテーションを付与するなら JSpecify を使おう! JSR-305, Spring Framework annotation を 使っている⼈は JSpecify に移⾏しよう!
© LY Corporation 19 JSpecify のアノテーションって 具体的にどうつけたらいいの? Java ライブラリ側で必要な対応 03
© LY Corporation JSpecify のアノテーションは 4 種類 (1) 20 •
@Nullable • 型が null 許容である時に使う • フィールド、返り値、引数等に付与できる • @NonNull • 型が null を許容しない時に使う • 付与できる箇所は上と同じ • だが、次に⽰す @NullMarked の⽅を使う ケースが多く、こちらを使う機会は少なそう https://jspecify.dev/docs/user-guide/ static @Nullable String foo(@NonNull String x) { return x.isEmpty() ? null : x; } static @NonNull String bar(@Nullable String x) { return x == null ? "" : x; }
© LY Corporation JSpecify のアノテーションは 4 種類 (2) 21 •
@NullMarked • モジュール、パッケージ、クラス、メソッド等に 付与でき、対象を⼀括でnonnull 扱いにできる • @Nullable がある場合はそちらが優先 https://jspecify.dev/docs/user-guide/ @NullMarked class Strings { static @Nullable String foo(String x) { return x.isEmpty() ? null : x; } } • @NullUnmarked • NullMarked を打ち消して、何もアノテーションをつけていないのと同じ状態にする • コードベースに対して段階的にアノテーションを導⼊したい時に使⽤できる
© LY Corporation アノテーション付与戦略 22 • NonNull か Nullable かはどうやって判定する?
• 外部ライブラリの場合、まずは依存ライブラリのドキュメントを読もう • ドキュメントに記載がなく、実装から⼿掛かりを探るには…… • return null; があればそのメソッドの返り値は nullable であろう • もし if (parameter == null) みたいなのがあればそのパラメータは nullable であろう • あるフィールドが null あるいは null になりうる値を代⼊されていたら、その フィールドは nullable であろう https://jspecify.dev/docs/applying/
© LY Corporation アノテーション付与の順序 23 • 基本的には、他のクラスやパッケージへの依存が少ないクラスから始め、 それが終わったら呼び出し元へと外側へ進んでいく 1. null
になりうるものについて @Nullable を付与していく 1. 付与し終わったら @NullMarked をつける 2. まだ注釈付与が間に合っていない部分があればその部分に @NullUnmarked をつける 2. NullAway などの静的解析ツールによりチェック 3. Kotlin から呼び出してみて、Platform Type が⽣じないか確認 https://jspecify.dev/docs/applying/
© LY Corporation 補⾜: NullAway は何をチェックしてくれる? 24 • アノテーションと実装の齟齬や、アノテーション同⼠の⽭盾を検出 •
@NonNull と annotate した変数に null を代⼊している • 引数が @Nullable で、null チェックをせずそのまま値を返却しているが、 返り値の値は @NonNull になっている • 変数が @Nullable なのに、null に対して⾏うと NPE が発⽣する操作を ⾏っている • 逆に以下のようなものは検出できない • @NonNull でいいのに @Nullable になっている https://github.com/uber/NullAway/wiki/Error-Messages
© LY Corporation 実際の進め⽅ 25 • 先述の付与戦略を組み込んだ AI Agent ⽤の
skills を作成 (以下は指⽰の概略) 1. 複数モジュールからなるレポジトリの場合、他のクラスやパッケージへの依存が少ない モジュールを特定しそれから着⼿する 2. すべてのフィールド・パラメータ・返り値について「API 仕様ドキュメントの確認」 「実装コードのシグナル確認」を指⽰ 3. nullability 判定と根拠を表形式でユーザに提⽰し、承認を得る 4. @Nullable アノテーション付与 -> package-info.java を作成し @NullMarked 付与 5. ビルド & テスト (NullAway の警告もここでチェック。必要に応じて修正) 6. 利⽤者への影響を分析。対象モジュールの public API について以下が存在する場合は マイナーバージョンアップ & リリース周知の必要性を報告 a. メソッドの返り値、フィールドの getter の返り値が nullable に確定するケース b. メソッドのパラメータが non-null に確定するケース
© LY Corporation 実際やってみてわかってきたこと 26 • 依存ライブラリのドキュメントに nullability が明⽰されているかによって難易度が変わる •
API docs がないと、ライブラリの関数の返り値が null になりうるかどうかを ソースコードを読みにいって調べる必要が⽣じる • 当初は外部に露出する公開 API のみアノテーションを付与する⽅針も考えていたが、 結局ソースコード全体に付与するアプローチを採った • 公開 API のメソッドが内部 DTO を返り値に持つ場合が多く、結局それらの nullability を調査することになる • 公開 API に全て @NullMarked をつける / それ以外に @NullUnmarked をつけるの は⾯倒な上つけ忘れを招く • 外部から⾒えなくても、内部実装で NPE が⽣じるのを防げる
© LY Corporation 注意点 (1) 27 • Jackson でデシリアライズされるクラスについて。API 仕様上
null になり得ない ことを理由にフィールドを @NonNull に設定しておくと、NullAway に怒られる • 理由: NullAway はコンストラクタ終了時にすべての @NonNull フィールドが 初期化されているかを検査するため、setter 経由で後から値が⼊るフィールドに 対して偽陽性の警告が出る • 対処法: non-null フィールド初期化チェックをスキップするためにクラスに @SuppressWarnings(“NullAway.Init”) をつけるか、NullAway の設定 (-XepOpt:NullAway:ExternalInitAnnotations) を利⽤するのが良い https://github.com/uber/NullAway/wiki/Configuration
© LY Corporation 注意点 (2) 28 • JSR-305 annotation から移⾏する場合は
array のアノテーションに注意を! https://jspecify.dev/docs/using/#if-your-code-already-uses-jsr-305-annotations @Nullable Object[] • JSpecify で array ⾃体を nullable にしたいなら Object @Nullable [] とすべき。 @Nullable の直後に来たものが nullable になると覚えると良い JSR-305: 「array ⾃体が nullable」 JSpecify: 「nullable である object の array」
© LY Corporation 補⾜: アノテーションのつけ間違いに注意 29 • たまに外部ライブラリ側が JSpecify annotation
をつけ間違えていることが あり、利⽤者側で問題が発⽣ • nullable なものが誤って nonnull と指定され、Kotlin でのコンパイル エラーを招いた例 (reactor-core#4151) • 同様に Spring Security でも誤った nonnull 指定があり、NullAway の 偽陽性が発⽣したため patch (spring-security#19156) を提出するなど • つけ間違いは利⽤者に混乱を招くので注意を!
© LY Corporation この部分は どうやったらいいんだ? Platform Type の検出⽅法 04
© LY Corporation Platform Type の存在に気づくのは難しい 31 • IntelliJ IDEA
上で変数をホバーすれば Platform Type であることはわかるが、 特に Problem にも表⽰されないし、Qodana などの CLI ツールでも引っかからない • Kotlin のリンタである detekt には HasPlatformType というルールがあるが、これも Kotlin の公開 API に platform type が露出している場合しか検出してくれない • というわけで、Kotlin のソースコードの中に潜む Platform Type を検出する detekt のカスタムルールを⾃作しました • https://github.com/ternbusty/detekt-platform-type • detekt 2.0.0-alpha.3 に依存しており、あくまでも experimental なものです
© LY Corporation Platform Type はどうやって作られる? 32 Kotlin ソースコード (.kt)
PSI Program Structure Interface Kotlin Frontend Compiler FIR Frontend Intermediate Representation .class Java 関数の呼び出しがあった場合 Java の型を Kotlin に変換する処理を⾏う アノテーションがない場合は Platform Type となる IR Kotlin Backend Compiler 型の解決などが⾏われる
© LY Corporation Platform Type はどうやって作られる? 33 Kotlin ソースコード (.kt)
PSI Program Structure Interface Kotlin Frontend Compiler FIR Frontend Intermediate Representation .class IR Kotlin Backend Compiler detekt (Full Analysis Mode) PSI・FIR にアクセスし、 Platform Type を検出できる
© LY Corporation Rule 1: PlatformTypeAudit 34 • Platform Type
が検出され次第問答無⽤でアラートする Rule • Kotlin コード側で正しい null ハンドリングをしていても検出される • Kotlin のコード修正ではなく、依存先 Java レポジトリのアノテーション付与の必要性を 判断するためのものなので、Kotlin 側の CI 等で⽤いるのは避けた⽅が良い Platform Type を 検知してエラーに Kotlin 側で安全な ハンドルをしていても エラーになる仕様
© LY Corporation Rule 2: PlatformTypeUnhandled 35 • Platform Type
を正しくハンドリングしていない場合のみアラートする Rule • 検出した Platform Type のうち、正しくハンドルされておらず、NPE を引き起こす可能性が あるもののみ報告する • Kotlin 側のコードが、正しく Platform Type をハンドルできているかを知るための Rule なので、Kotlin 側の CI に⼊れても良い • 以下のように正しく handle しているものについては silence される val withFallback: String = javaClass.getNullableString() ?: "default" val safeStr: String? = javaClass.getNullableString() String? に格納している エルビス演算⼦を使って ハンドリング
© LY Corporation まとめ 36
© LY Corporation • 特にコンパイル時の挙動や実⾏時の挙動・ パフォーマンスに影響はなし • ただし、アプリケーション側でのメリット として、ライブラリ側が Null
を返すか 否かが明確になるので、 • JSpecify を解釈できる IDE で、 静的解析の性能が上がる • NullAway などの静的解析ツールを 導⼊していた場合、正確な結果が 出るようになる • Platform Type がなくなり、 null ハンド リングが必要な部分はコンパイル時に きちんとハンドリングが要求されるように なるのがメリット • 逆にハンドリングをしないと、 Kotlin 2.1 以降ではコンパイル エラーになるので注意 • エラーにならないようにコンパイル オプションで変えることはできるので、 アプリケーション側で即座の実装改修が 必要とされるわけではない Java Kotlin 37 結局 JSpecify アノテーションをつけるとどうなる?
© LY Corporation Take Home Message 38 • Java 側のコードにアノテーションを付与すると、Kotlin
側での Platform Type が 消え、Java ライブラリを安全に利⽤できるようになる • Kotlin だけでなく、そのライブラリを使う Java のアプリケーションにも恩恵がある • Spring Boot 4 時代なので JSpecify のアノテーションを使うべき • detekt カスタムルールを利⽤すれば、Java 側のアノテーション付与の必要性や、 Kotlin 側でのハンドリング不⾜が判定できる
© LY Corporation Thank You