WWDC25:Explore Swift and Java interoperability

先日の Recap イベント で知った SwiftJava について。

話されているこの方、try! Swift 2025 でもご登壇されていた。あいにく筆者はスタッフをしていたので聴講できなかったが、会場で何度もお見かけしていたので、サムネからすぐにピンときた。


0:00 – Introduction & Agenda

  • SwiftとJavaの相互運用(インターオペラビリティ)を紹介
  • Swiftを他言語の既存コードベースに段階的に導入できるメリット
    • 書き換えずそのままに、Swiftでの新しい機能追加や置き換えが可能
    • Swiftで多言語のライブラリ、多言語でSwiftのライブラリを利用可能
  • Swiftと他言語の連携は言語だけでなく、CMakeやGradleなど各エコシステムのビルドツールとも統合
  • SwiftのC言語はじめ多言語との相互運用の歴史
  • 相互運用の方向性:Java interoperability は両方向に対応
    • Call Java from Swift
    • Call Swift from Java

2:41 – Runtime differences

  • JavaとSwiftのランタイムの違いを解説
  • 両言語ともクラス継承、メモリ管理、ジェネリクス、例外処理など多くの共通点がある
  • 違いを意識しつつAPIを設計すれば、相互運用が可能

3:31 – Java Native methods

  • Java Native Interface(JNI)を使ったJavaからネイティブコード(Swift)呼び出しの仕組み
    • Java のネイティブメソッドは JNI API に含まれている
    • JNIは歴史が長く、パフォーマンス向上や既存ネイティブライブラリ利用のために使われる
  • ライブラリやツールを使わない従来手順で JNI を使うデモ
    • Java でネイティブ関数を定義、ネイティブコードを浸かって実装
    • 例では、Java オブジェクトである Integer を引数・戻り値に使用
    • Java コンパイラを使用:-h フラグ → Cヘッダーファイルが生成
      • JVM が呼び出すファイル
      • インターフェイスの命名が長い
    • これを Swift で実装
  • JNIの利用は手順が多く、Cヘッダーやシグネチャの一致などミスが起きやすい
  • オブジェクトのライフタイム管理も難しい

6:29 – SwiftJava

  • Swift と Java の相互運用を支援する新プロジェクト「SwiftJava」を紹介
    • Swift パッケージ(JavaKit)
    • Javaライブラリ(SwiftKit)
    • コマンドラインツール (swift-java) で構成
  • swift-java コマンドによる生成結果(Swift ファイル)
    • インポートされたJavaクラスの定義が含まれている
    • @JavaMethod マクロで示される Java 型のメンバーメソッド経由で、Swift コードからアクセスできる
    • JNIExampleNativeMethods プロトコル:C ヘッダの代わり
    • @JavaImplementation でネイティブ関数を実装。必要な関数シグネチャはコンパイラが実装
    • @JavaMethod マクロの関数定義内で、Swift コード/Swift ライブラリを利用した実装が可能
  • JNI の煩雑さを解消し、ボイラープレートを削減し、安全かつ効率的な連携を実現
  • SwiftJava を使うことで、型安全なコード生成やオブジェクト管理が容易に

10:13 – Call Java from Swift

  • Swift から Java ライブラリを利用する方法
  • Gradle 連携で Java の依存解決も自動化
  • 依存関係の3つの要素:Artifact ID, Group ID, Version をコロンで繋ぎ、 swift-java.config の dependencies に追加
  • Swift Package Manager プラグインやコマンドラインツールで Java ライブラリを Swift から簡単に呼び出せる(トレードオフあり)
    • swift build --disable-sandbox : セキュリティサンドボックス無効化が必要
    • swift-java resolve --module-name <module_name> : 依存関係の解決を手動起動する必要あり
  • JavaKit による JDK ラッパー型やオブジェクトのライフタイム管理もサポート
    • Swift プロセスで JVM 起動
      • let jvm = try JavaVirtualMachine.shared()

14:01 – Call Swift from Java

  • Java から Swift ライブラリを利用する方法
  • Swift の型や関数を Java クラスとして自動生成し、Java からシームレスに呼び出し可能
  • JNIではなく、Java 22 以降の Foreign Function and Memory API を活用
  • 例:struct SwiftyBusiness – 構造体定義で、プロパティ、イニシャライザ、メソッドを持つ
    • struct は値型で、安定したオブジェクトIDがない → Java オブジェクトで表現不可
    • swift-java コマンド:Swift 型ヘのアクセサである .java ファイル(Java クラス)生成
    • .swift も含めた .jar ファイルが生成
    • 構造体が Java クラスとして実装され、メソッドも Java シグネチャで定義される
      • 内部的に Foreign Function API でネイティブ呼び出しされる
  • Confined な SwiftArena(メモリ管理、有効期限管理)の使用で、安全かつ効率的なリソース解放を実現
    • SwiftArena.ofConfined() による、try-with-resource を使用したメモリ管理
    • GCに依存せず最善のパフォーマンスを実現可能

おまけ

ChatGPT が案出ししてくれた、SwiftJava の実験案10選。

iOS兼Androidアプリエンジニアとしては、Android 開発と連動できれば嬉しいが、、Kotlin が主流な昨今において果たして。Jetpack Compose のコード生成はできないと思う、、

1. “書いた Swift をそのまま Android でも”
  • ドメインロジックやアルゴリズムを Swift で実装し、SwiftJava CLI で Java ラッパを吐き出して Android に組み込む。Gradle が依存解決・ビルドを面倒見てくれるので iOS ⇄ Android の 100 % 共有コード が現実的に。 
2. Java ライブラリをサクッと呼ぶ Swift サーバー
  • Vapor や Hummingbird など Swift サーバーアプリから Apache Lucene/Kafka/Spark まで JAR ごとインポート。swift-java resolve がトランジティブ依存を丸ごと解決し、Swift 側は import JavaLucene で即検索エンジン化。 
3. Swift 製暗号モジュールを Java へ“輸出”
  • セキュアかつ GC フリーな Swift ライブラリを生成し、JVM とは Java 22 の Foreign Function & Memory API で橋渡し。Java 側は try-with-resources で自動メモリ管理、Swift 側は Arena で安全――金融/ブロックチェーン案件に映える。 
4. Jetpack Compose コンポーネントを Swift マクロで自動生成
  • SwiftUI ライクな DSL → マクロ展開で Compose UI を吐くツールチェインを自作。デザイナーが SwiftUI プレビューで確認 → ボタン一発で Android 版 UI を生成、という“プラットフォーム超えデザインシステム”を実現。
5. JVM 大規模データ処理をローカル ML 推論に転用
  • Java の Deeplearning4j モデルを iOS アプリに同梱し、Swift から呼び出して 完全オフラインの画像分類。モバイルでも GDPR/個人情報保護の要件をクリアしつつ高精度推論。
6. Minecraft/IntelliJ プラグインを Swift で書く
  • プラグイン API は Java だが、Swift 側でコアロジックを書くことで Swift Concurrency で並列 AIResult Builders で DSL などモダン機能をプラグインにも注入。
7. Spring Boot × Swift で“二刀流”マイクロサービス
  • コントローラ層は Java(Spring)、ドメイン層を Swift で実装。Swift の値型 & 不変データでビジネスロジックを堅牢にしつつ、既存の Spring インフラ(Actuator/Observability)をそのまま享受。
8. JUnit ↔︎ XCTest 相互呼び出しでクロスプラットフォーム CI
  • SwiftJava で JUnit テストから Swift の XCTest を直接呼び出し、“片方落ちたら両方真っ赤”な 一体化テストレポート を生成。モノレポの CI をシンプルに。
9. SwiftArena × Project Loom で“協調コルーチン”
  • Java 側の仮想スレッド(Loom)と Swift の Structured Concurrency を相互ラップし、クロスランタイムの高スループット IO を研究。フルスタック並列処理オタク歓喜。
10. “Swift 製 DSL→JVM バイトコード”コンパイラ
  • Swift Macro で DSL を解析、SwiftJava で ASM(Java バイトコード生成ライブラリ)を呼び出して ネイティブに JVM バイトコードを吐く。Swift 製ビルドツールやスクリプトエンジンだって夢じゃない。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です