技術 約8分で読めます

OracleがJavaにV8とCPythonを丸ごと組み込む「Project Detroit」をOpenJDKに提案

OracleがJavaOne 2026(カリフォルニア州レッドウッドシティ、3月17日)でProject Detroitを発表し、OpenJDKへのプロジェクト提案として提出した。JavaのビルドプロセスにV8(GoogleのJavaScriptエンジン)とCPython(Pythonのリファレンス実装)を直接組み込み、javax.script APIから呼び出せるようにする構想だ。

「JavaにJavaScriptを載せる」と聞くと逆じゃないかと思うかもしれない。だがこれにはJava側の多言語連携が10年近く迷走してきた背景がある。

Javaの多言語連携、3度目の挑戦

Javaが他言語と連携する仕組みは過去に2回失敗している。Project Detroitは3度目の挑戦にあたる。

Nashornの時代(JVM上にJavaScriptを再実装)

Java 8(2014年)で導入されたNashornは、JVM上でJavaScriptを動かすスクリプトエンジンだった。それ以前のRhinoエンジンの置き換えとして登場し、javax.script APIを通じてJavaコードからJavaScriptを呼び出せた。

問題はECMAScriptの進化速度だった。ES2015以降、JavaScriptの仕様は毎年更新され、async/await、モジュール、WeakRef、Proxy、ジェネレータと次々に新機能が追加されていく。NashornはこれをJVM上で一から再実装し続ける必要があった。V8やSpiderMonkeyのように数百人規模のチームが取り組んでいるエンジンの機能を、Oracle単独で追いかけ続けるのは現実的ではなかった。

バージョン状態
Java 8(2014)Nashorn導入
Java 11(2018)非推奨化(JEP 335)
Java 15(2020)完全削除(JEP 372)

Java 15でNashornが削除された後、javax.script API自体は残ったが、実装がなくなった。JavaからJavaScriptを呼ぶ標準的な方法が消えた。

GraalVMでJVMごと置き換えるアプローチ

GraalVMはOracleが開発した多言語対応のJVM実装で、Truffle言語実装フレームワーク上にGraalJS(JavaScript)やGraalPy(Python)を構築していた。JVM自体を丸ごと置き換える形で多言語サポートを実現するアプローチだ。

技術的には優れていたが、導入ハードルが高かった。

  • HotSpot(標準JVM)からGraalVMへの移行が必要
  • 既存の運用・監視ツールとの互換性問題
  • GraalVMのJITコンパイラはHotSpotのC2 JITと動作が異なり、パフォーマンス特性が変わる
  • エンタープライズ環境で「JVMの差し替え」は運用チームが嫌がる

そして2025年9月、OracleはGraalVMをJavaのバージョンサイクルから切り離した。GraalVM for JDK 24が最後のJava SE製品としてのリリースとなり、以降はGraalJS・GraalPyなど非Java言語サポートに注力する方向に転換した。実験的に含まれていたGraal JITコンパイラもOracle JDKから廃止され、標準のC2 JITへの移行が推奨された。

GraalVMがJavaのエコシステムから離脱したことで、JavaからJavaScript・Pythonを呼ぶ公式な手段がまた失われた。

Project Detroitは再実装をやめた

Project Detroit自体は2018年に一度立ち上がっている。当時はJavaScript(V8)のみが対象だったが、スポンサーグループを失い、2024年9月に正式に解散した。

2026年2月、Sundararajan Athijegannathanを中心に再提案された。今回はPythonサポートが追加され、OpenJDKメーリングリストでの投票を経て正式にプロジェクト化が進んでいる。

3度目の挑戦で決定的に変わったのは、「JavaScriptやPythonをJVM上で再実装する」というアプローチを完全に捨てたことだ。

「再実装」をやめて「組み込む」設計にした理由

OracleのVP of Software Development、Bernard Traversatはこう説明している。

「過去のNashornでは、JavaScriptをJVMの上にフル実装しようとした。問題は、JavaScriptのエコシステム全体がV8やNode.js(V8ベース)の上に構築されているということだ。常に流れに逆らって泳ぐことになる」

V8はGoogleが開発するオープンソースのJavaScriptエンジンで、Chrome、Node.js、Deno、Cloudflare Workersなどが採用している。ECMAScript仕様への追従はもちろん、TurboFanによるJITコンパイル、Orinoco GCなどの最適化が常に進んでいる。CPythonはPythonの公式リファレンス実装で、Python Enhancement Proposals(PEP)で仕様が変更されるたびに最初に実装が反映される。

これらを再実装するのではなく、ネイティブランタイムをそのままJVMプロセスに組み込む。V8で動くJSはProject Detroitでもそのまま動くし、仕様追従もV8/CPythonのアップデートを取り込むだけで済む。各コミュニティの最適化がそのまま使え、再実装に起因するコーナーケースの挙動差異もなくなる。

FFM APIが実現の鍵

ではなぜ2018年にはうまくいかなかったのか。技術的な鍵はJava 22(2024年3月)で正式化されたForeign Function & Memory(FFM)API(JEP 454)にある。

FFM APIはProject Panamaの成果物で、JNI(Java Native Interface)に代わるネイティブコード連携の仕組みだ。JNIは1996年から存在していたが、ボイラープレートが多く、メモリ管理が危険で、パフォーマンスオーバーヘッドも大きかった。

比較項目JNIFFM API
導入Java 1.1(1997年)Java 22(2024年)
ネイティブコード呼び出しC/C++のヘッダ生成が必要Javaコードのみで完結
メモリ管理手動管理、GCと連携しにくいMemorySegmentで安全に管理
パフォーマンスJNIオーバーヘッドあり低オーバーヘッド

FFM APIにより、V8やCPythonのCライブラリを「非常に薄いレイヤー」でJavaから呼び出せるようになった。2018年時点ではJNIしかなく、V8を組み込んでも実用的なパフォーマンスが出せなかった。FFM APIの正式化がProject Detroit再始動の技術的な前提条件だった。

ヒープ分離によるセキュリティモデル

Project Detroitではヒープを完全に分離する設計を採用している。

graph LR
    A[JVMプロセス] --> B[Javaヒープ]
    A --> C[V8ヒープ]
    A --> D[CPythonヒープ]
    B -.->|javax.script API| C
    B -.->|javax.script API| D

Java、V8、CPythonはそれぞれ独立したメモリ空間(ヒープ)を持つ。言語間のやり取りはjavax.script APIを通じたデータのコピーで行われる。つまり、JavaScriptのコードがJavaのヒープに直接アクセスすることはできない。

GraalVMのTruffleフレームワークでは言語間でオブジェクトを共有する設計だったため、一方の言語の脆弱性が他方に波及するリスクがあった。Project Detroitのヒープ分離モデルは、サンドボックス的な分離を実現している。

具体的にどう使うのか

ビジネスロジックのスクリプティング

エンタープライズJavaアプリケーションでは、ビジネスルールを外部化したいケースが多い。保険の料率計算、ワークフローの分岐条件、バリデーションルールなどだ。これをJavaScriptで記述し、javax.script API経由で実行すれば、Javaアプリの再コンパイル・再デプロイなしにルール変更が可能になる。

Nashornが削除されて以来、この用途のために外部プロセスでNode.jsを立てたり、サードパーティのスクリプトエンジンに依存したりしていた現場は少なくない。

AI・MLライブラリへのアクセス

Python連携の最大のモチベーションはAI・機械学習だ。Georges Saab(Oracle Java Platform Group SVP)はこう述べている。

「Detroitの主な利点は、業界をリードするJavaとJavaScript、またはJavaとPythonを、両方の技術を一緒に使いたい場所で組み合わせられることだ」

PyTorch、NumPy、scikit-learn、pandas、HuggingFace Transformersといったエコシステムの資産がJavaプロセス内から直接呼び出せる。現状ではJavaアプリケーションからPythonのMLモデルを使うには、REST APIやgRPCでPythonサービスを別プロセスで立てるのが一般的だ。

graph TD
    subgraph 現状
        A1[Java App] -->|REST/gRPC| B1[Python ML Service]
        B1 --> C1[PyTorch / NumPy]
    end
    subgraph Project Detroit後
        A2[Java App] -->|javax.script API| B2[CPython in-process]
        B2 --> C2[PyTorch / NumPy]
    end

プロセス間通信が不要になり、レイテンシとインフラコストの両方が下がる。ただし、CPythonのGIL(Global Interpreter Lock)がJVMのマルチスレッドモデルとどう共存するかは、まだ詳細が公開されていない。

SSR(サーバサイドレンダリング)

JavaバックエンドからReactやVueのコンポーネントをサーバサイドでレンダリングする用途も考えられる。現状ではSSRのためにNode.jsプロセスを別途立てる必要があるが、V8がJVMプロセス内で動くなら、単一プロセスでJavaのビジネスロジックとReactのレンダリングを完結できる。

GraalVMとの関係と棲み分け

GraalVMは消えたわけではない。GraalVMはJavaのバージョンサイクルから離脱しただけで、GraalJS・GraalPy・GraalWasmなどの多言語サポートは独自のリリースサイクルで継続している。

項目Project DetroitGraalVM
JVMの変更不要(HotSpotのまま)GraalVM JVMに置き換え
言語実装V8/CPythonをそのまま組み込みTruffle上で再実装
ヒープ完全分離共有可能
エコシステム互換性完全(ネイティブランタイム)ほぼ互換(再実装由来の差異あり)
対象ユーザーOpenJDK/HotSpotユーザーGraalVMエコシステムのユーザー
リリースサイクルOpenJDKに統合予定独自サイクル

棲み分けとしては、「JVMを変えたくない」大多数のJavaユーザーにはProject Detroit、GraalVMのNative ImageやTruffleエコシステムを活用しているユーザーにはGraalVMという形になる。

現在のステータス

OpenJDKのCompiler Groupがスポンサーとなり、detroit-js(JavaScript実装)とdetroit-python(Python実装)の2つのリポジトリで開発が進んでいる。GPLv2ライセンスでの公開だ。

まだOpenJDKへの統合提案段階であり、どのJavaバージョンに含まれるかは確定していない。JavaScriptとPythonが初期対象で、他の言語も将来的に追加する計画がある。


3度目の正直でうまくいくかはまだわからないが、FFM APIという技術的基盤が揃った今回は過去2回とは前提が違う。