# 機能設計書 139-Java言語バインディング

## 概要

本ドキュメントは、TensorFlowのJava言語バインディングの機能設計について記載する。

### 本機能の処理概要

Java言語バインディングは、Java/JVM環境からTensorFlowの機能を利用するためのJNI（Java Native Interface）ベースのAPIを提供する。

**業務上の目的・背景**：JavaはエンタープライズシステムやAndroidアプリケーションで広く使用されており、Java環境からTensorFlowモデルの推論を実行するニーズが大きい。JNIを通じてTensorFlowのC言語APIを呼び出すことで、JavaネイティブなオブジェクトとしてTensorFlowの機能を利用できる。

**機能の利用シーン**：JavaサーバサイドアプリケーションやAndroidアプリからのモデル推論、計算グラフの構築・実行、テンソルの生成・操作、SavedModelの読み込みなど。

**主要な処理内容**：
1. Tensor型：多次元配列の生成・値の読み取り・メモリ管理
2. Graph型：計算グラフの構築・オペレーション操作・Protocol Bufferインポート
3. Session型：計算グラフの実行（Runner.run()）・リソース管理
4. SavedModelBundle型：SavedModel形式モデルの読み込み
5. EagerSession型：Eager実行モード
6. Operation/Output型：グラフ内のオペレーションとその出力
7. OperationBuilder型：オペレーションの構築
8. Ops（core/Constant, Zeros, Gradients）：高水準の操作API
9. アノテーションプロセッサ（@Operator）：コード自動生成

**関連システム・外部連携**：C言語API（No.141）を経由してTensorFlowランタイムと連携する。

**権限による制御**：特になし。

## 関連画面

本機能は画面機能マッピングにおいて直接的な関連画面は定義されていない。

## 機能種別

外部連携 / 言語バインディング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| exportDir | String | Yes（SavedModelBundle.load） | SavedModelのエクスポートディレクトリ | 有効なパス |
| tags | String[] | Yes（SavedModelBundle.load） | モデルのタグ | 文字列配列 |
| config | byte[] | No（Session constructor） | ConfigProtoのシリアライズバイト列 | 有効なProtocol Buffer |
| graph | Graph | Yes（Session constructor） | 計算グラフ | 有効なGraphインスタンス |

### 入力データソース

Javaプログラムからのプログラム的なAPI呼び出し。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Tensor<T> | Tensor | 型パラメータ付きテンソル |
| Session | Session | 計算セッション |
| Graph | Graph | 計算グラフ |
| SavedModelBundle | SavedModelBundle | 読み込まれたSavedModel |
| List<Tensor<?>> | List | Session.Runner.run()の実行結果 |

### 出力先

Javaアプリケーションのメモリ空間。

## 処理フロー

### 処理シーケンス

```
1. ネイティブライブラリのロード
   └─ NativeLibrary.load() でJNIライブラリを動的ロード

2. SavedModelの読み込み（一般的なパターン）
   └─ SavedModelBundle.load(exportDir, tags)
       └─ JNI → C.TF_LoadSessionFromSavedModel

3. セッションの作成・実行
   └─ new Session(graph) または new Session(graph, config)
   └─ session.runner().feed("input", tensor).fetch("output").run()
   └─ 結果テンソルの取得と値の読み取り

4. リソース解放
   └─ try-with-resources またはclose()で明示的に解放
```

### フローチャート

```mermaid
flowchart TD
    A[Java Application] --> B{操作}
    B -->|モデル推論| C[SavedModelBundle.load]
    B -->|グラフ実行| D[new Graph + new Session]
    C --> E[bundle.session.runner.feed.fetch.run]
    D --> F[session.runner.feed.fetch.run]
    E --> G[List of Tensor results]
    F --> G
    G --> H[tensor.floatValue / copyTo]
    H --> I[close resources]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-139-01 | AutoCloseable | Graph, Session, Tensor, SavedModelBundleはAutoCloseableを実装。try-with-resources推奨 | 常時 |
| BR-139-02 | リソース解放必須 | リソースはclose()で明示的に解放する必要がある（WARNINGとして文書化） | 常時 |
| BR-139-03 | スレッドセーフ | Session, Graphはスレッドセーフ。Tensorはスレッドセーフでない | 並行処理時 |
| BR-139-04 | JNI依存 | ネイティブライブラリ（libtensorflow_jni）が必要 | 常時 |
| BR-139-05 | 参照カウント | Graphは内部で参照カウント（refcount）を管理 | Session連携時 |

### 計算ロジック

特段の計算ロジックはない。TensorFlowランタイムへの委譲。

## データベース操作仕様

本機能にデータベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| TensorFlowException | ランタイムエラー | TensorFlowの操作がエラーを返した場合 | エラーメッセージを確認 |
| IllegalArgumentException | 引数エラー | 不正なConfigProtoバイト列を指定した場合 | 有効なProtocol Bufferを使用 |
| IllegalStateException | 状態エラー | close()済みのオブジェクトを使用した場合 | ライフサイクルを確認 |
| UnsupportedOperationException | 非対応操作 | Javaバインディングで未サポートの操作 | Python APIの使用を検討 |

### リトライ仕様

該当なし。

## トランザクション仕様

該当なし。

## パフォーマンス要件

JNI呼び出しにオーバーヘッドが存在する。大量のテンソル生成・解放はGCへの負荷となるため、try-with-resourcesでの即時解放を推奨。ByteBuffer（DirectBuffer）を使用したゼロコピーテンソル生成が高効率。

## セキュリティ考慮事項

- ネイティブライブラリのロードパスに注意（信頼できないパスからのロードを避ける）
- close()済みオブジェクトのnativeHandleアクセスはsynchronizedブロックで保護されている

## 備考

- @Operatorアノテーションによるオペレーションクラスの自動生成（OperatorProcessor）
- EagerSessionによるEager実行モードもサポート
- Tensorは型パラメータ（`Tensor<T>`）により型安全性を提供
- ByteBuffer, FloatBuffer, IntBuffer等のNIO Bufferを直接テンソルに変換可能

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Tensor.java | `tensorflow/java/src/main/java/org/tensorflow/Tensor.java` | Tensor<T>クラス。AutoCloseable実装、nativeHandleによるC連携 |
| 1-2 | DataType.java | `tensorflow/java/src/main/java/org/tensorflow/DataType.java` | TensorFlowデータ型のJavaマッピング |
| 1-3 | Shape.java | `tensorflow/java/src/main/java/org/tensorflow/Shape.java` | テンソル形状の表現 |

**読解のコツ**: nativeHandle（long型）がC言語側のオブジェクトポインタを保持するパターンに注目。synchronized(nativeHandleLock)でスレッドセーフ性を確保。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SavedModelBundle.java | `tensorflow/java/src/main/java/org/tensorflow/SavedModelBundle.java` | SavedModel読み込みAPI |
| 2-2 | TensorFlow.java | `tensorflow/java/src/main/java/org/tensorflow/TensorFlow.java` | バージョン情報、ネイティブライブラリロード |

#### Step 3: グラフとセッションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Graph.java | `tensorflow/java/src/main/java/org/tensorflow/Graph.java` | Graph型の実装 |
| 3-2 | Session.java | `tensorflow/java/src/main/java/org/tensorflow/Session.java` | Session型とRunner内部クラス |

**主要処理フロー**:
- **Graph.java 28行目**: `public final class Graph implements ExecutionEnvironment, AutoCloseable`
- **Graph.java 31-33行目**: コンストラクタ - allocate()でJNI経由のネイティブGraphを生成
- **Graph.java 47-64行目**: close() - 参照カウントが0になるまで待機してからdelete
- **Session.java 48行目**: `public final class Session implements AutoCloseable`
- **Session.java 51-53行目**: コンストラクタ（Graph必須）
- **Session.java 65-75行目**: 設定付きコンストラクタ（ConfigProtoバイト列）

#### Step 4: 操作APIを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Scope.java | `tensorflow/java/src/main/java/org/tensorflow/op/Scope.java` | 操作スコープ管理 |
| 4-2 | Constant.java | `tensorflow/java/src/main/java/org/tensorflow/op/core/Constant.java` | 定数操作 |
| 4-3 | Gradients.java | `tensorflow/java/src/main/java/org/tensorflow/op/core/Gradients.java` | 勾配計算 |

### プログラム呼び出し階層図

```
Java Application
    |
    +-- SavedModelBundle.load(exportDir, tags)
    |       +-- JNI → C.TF_LoadSessionFromSavedModel
    |       +-- return SavedModelBundle(Graph, Session, MetaGraphDef)
    |
    +-- new Graph()
    |       +-- allocate() → JNI → C.TF_NewGraph
    |
    +-- new Session(graph)
    |       +-- allocate(nativeHandle) → JNI → C.TF_NewSession
    |
    +-- Session.Runner
    |       +-- feed(name, tensor) → inputsをリストに追加
    |       +-- fetch(name) → outputsをリストに追加
    |       +-- run() → JNI → C.TF_SessionRun
    |               +-- return List<Tensor<?>>
    |
    +-- Tensor.create(value)
    |       +-- JNI → C.TF_NewTensor
    |
    +-- close()
            +-- JNI → C.TF_DeleteSession / C.TF_DeleteGraph
```

### データフロー図

```
[入力]                    [処理]                          [出力]

Java objects        ---> Tensor.create()            ---> Tensor<T> (native memory)
(int, float,             |
 float[][], etc.)        +-> JNI → C.TF_NewTensor

SavedModel dir      ---> SavedModelBundle.load()   ---> SavedModelBundle
                         |                                {Graph, Session, MetaGraphDef}
                         +-> JNI

feed Tensors        ---> Session.Runner.run()       ---> List<Tensor<?>>
fetch operations         |
                         +-> JNI → C.TF_SessionRun
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Tensor.java | `tensorflow/java/src/main/java/org/tensorflow/Tensor.java` | ソース | テンソル型 |
| Graph.java | `tensorflow/java/src/main/java/org/tensorflow/Graph.java` | ソース | 計算グラフ |
| Session.java | `tensorflow/java/src/main/java/org/tensorflow/Session.java` | ソース | セッション（実行） |
| SavedModelBundle.java | `tensorflow/java/src/main/java/org/tensorflow/SavedModelBundle.java` | ソース | SavedModel読み込み |
| Operation.java | `tensorflow/java/src/main/java/org/tensorflow/Operation.java` | ソース | 操作インターフェース |
| Output.java | `tensorflow/java/src/main/java/org/tensorflow/Output.java` | ソース | 操作の出力 |
| DataType.java | `tensorflow/java/src/main/java/org/tensorflow/DataType.java` | ソース | データ型定義 |
| Shape.java | `tensorflow/java/src/main/java/org/tensorflow/Shape.java` | ソース | テンソル形状 |
| TensorFlow.java | `tensorflow/java/src/main/java/org/tensorflow/TensorFlow.java` | ソース | バージョン・ライブラリロード |
| EagerSession.java | `tensorflow/java/src/main/java/org/tensorflow/EagerSession.java` | ソース | Eager実行モード |
| NativeLibrary.java | `tensorflow/java/src/main/java/org/tensorflow/NativeLibrary.java` | ソース | ネイティブライブラリロード |
| Scope.java | `tensorflow/java/src/main/java/org/tensorflow/op/Scope.java` | ソース | 操作スコープ |
| OperatorProcessor.java | `tensorflow/java/src/gen/java/org/tensorflow/processor/OperatorProcessor.java` | 生成ソース | @Operatorアノテーションプロセッサ |
| GraphOperationBuilder.java | `tensorflow/java/src/main/java/org/tensorflow/GraphOperationBuilder.java` | ソース | グラフ操作ビルダー |
| EagerOperationBuilder.java | `tensorflow/java/src/main/java/org/tensorflow/EagerOperationBuilder.java` | ソース | Eager操作ビルダー |
