Java RMI

[cover photo]
  • 2002年06月 発行
  • 648ページ
  • ISBN4-87311-086-6
  • 原書: Java RMI
  • フォーマット

この商品は品切れ再入荷未定です

RMI(Remote Method Invocation)とはJavaでリモートメソッドの呼び出しを実現するAPIで、自分のコンピュータからネットワークに接続されているほかのコンピュータのリソースを利用できるようにします。本書は、JavaでRMIを使った分散アプリケーションを開発する際に必要となるRMIの概念、実装および分散アプリケーションの開発方法を詳細に解説しています。RMIだけではなく、分散オブジェクト設計の解説書としても有用な一冊です。

はじめに

I部 RMIアプリケーションの基礎:設計と実装

1章 ストリーム
        1.1 中心となるクラスたち
                1.1.1 InputStream
                1.1.2 IOException
                1.1.3 OutputStream
        1.2 ファイルの中身を表示する
        1.3 ストリームを階層化する
                1.3.1 ファイルの圧縮
                1.3.2 便利な中間ストリーム
        1.4 リーダーとライター
                1.4.1 ViewFileアプリケーションの改良

2章 ソケット
        2.1 インターネットの定義
                2.2 ソケット
                2.2.1 ソケットの作成
                2.2.2 プロトコルとメタデータ
        2.3 ServerSocket
                2.3.1 accept( )メソッド
                2.3.2 簡単なWebサーバ
        2.4 ソケットのカスタマイズ
        2.5 特殊用途のソケット
                2.5.1 ストリームを直接操作する
                2.5.2 もっと良い方法:ソケットをサブクラス化する
                2.5.3 特殊用途のソケット
                2.5.4 ファクトリ
                2.5.5 ソケットファクトリ
                2.5.6 セキュリティ
        2.6 SSLを使用する
                2.6.1 SSLハンドシェーク
                2.6.2 JSSE(JavaによるSSLの実装)を使用する
                2.6.3 前出のWebサーバの改良

3章 ソケットベースのプリンタサーバ
        3.1 ネットワークベースのプリンタ
        3.2 基本オブジェクト
        3.3 プロトコル
                3.3.1 オブジェクトのカプセル化と送信
                3.3.2 ネットワーク対応のラッパーオブジェクト
        3.4 アプリケーションのメイン部
                3.4.1 クライアントを書く
                3.4.2 アーキテクチャ図の描き直し
        3.5 改良点
                3.5.1 これらの改良を施すと

4章 RMIベースのプリントサーバ
        4.1 RMIの基本構造
                4.1.1 ネットワーク越しのメソッド呼び出し
                4.1.2 「値渡し」と「参照渡し」
        4.2 アーキテクチャ図の描き直し
        4.3 基本オブジェクトの実装
                4.3.1 Printerインタフェース
                4.3.2 プリンタの実装
                4.3.3 データオブジェクト
        4.4 サーバの残りの部分
        4.5 クライアントアプリケーション
        4.6 まとめ

5章 分散アプリケーションの具体例:バンキングアプリケーションの導入
        5.1 分散アプリケーションの具体例:バンキングシステム
        5.2 アーキテクチャのラフスケッチ
                5.2.1 ラフスケッチの5つの手順
        5.3 基本的な利用パターン
        5.4 その他の設計上の考慮点
                5.4.1 後回しにすること
                5.4.2 環境による制約
        5.5 バンキングアプリケーションの分散アーキテクチャ
        5.6 分散アプリケーションで発生する問題
                5.6.1 部分的障害
                5.6.2 ネットワークレイテンシ

6章 リモートサーバに関する決定事項
        6.1 ちょっとした偏向
        6.2 サーバ設計時の着眼点
                6.2.1 各サーバのインスタンスは貴重な(限りのある)共有リソースを必要とするか
                6.2.2 サーバを複数のマシンにうまく複製/拡張できるか
                6.2.3 単一サーバで典型的なクライアントとのやり取りを処理できるか
                6.2.4 サーバに複数のクライアントを同時に処理させることが容易にできるか
                6.2.5 コードが正しいかどうかを簡単に判断できるか
                6.2.6 サーバの障害はどれくらい破壊的か
                6.2.7 ソフトウェアの機能拡張と新機能の追加は容易か
        6.3 BankオプションとAccountオプションのどちらを実装すべきか

7章 リモートインタフェースの設計
        7.1 リモートインタフェース設計時の重要事項
                7.1.1 メソッドオブジェクトを渡すべきか
                7.1.2 引数としてオブジェクトとプリミティブ値のどちらを渡すべきか
                7.1.3 戻り値としてオブジェクトかプリミティブ値のどちらを受信すべきか
                7.1.4 個々のメソッド呼び出しは帯域幅を浪費するか
                7.1.5 1つの概念的な操作が1つのメソッド呼び出しに対応しているか
                7.1.6 インタフェースは正しい量のメタデータを公開しているか
                7.1.7 適切な分散例外のセットが特定されているか
        7.2 データオブジェクトの構築
                7.2.1 データオブジェクトはふつう機能メソッドを持たない
                7.2.2 インタフェースはデータオブジェクトを提供する
        7.3 部分的障害の対策

8章 バンキングサーバの実装
        8.1 サーバの構造
        8.2 サーバの実装
                8.2.1 UnicastRemoteObjectを拡張したサーバ
                8.2.2 UnicastRemoteObjectを拡張しないサーバ
                8.2.3 UnicastRemoteObjectを拡張する
        8.3 スタブとスケルトンの生成
                8.3.1 スケルトンの数を減らす(スケルトンなしで済ます)

9章 アプリケーションの残りの部分
        9.1 起動用コードに必要なもの
                9.1.1 サーバのライフサイクルという考え方
        9.2 実際の起動用コード
        9.3 テストアプリケーションの構築
        9.4 クライアントアプリケーションの構築
                9.4.1 サーバへのコネクションを保持したままにしない
                9.4.2 引数の妥当性チェックをできるかぎりクライアント側で行う
                9.4.3 実際のクライアントアプリケーション
        9.5 アプリケーションの配置


II部 スケーラビリティの実現

10章 直列化
        10.1 直列化はなぜ必要か
                10.1.1 オブジェクト生成をさらに堀り下げてみると
        10.2 直列化の利用
                10.2.1 ObjectOutputStream
                10.2.2 ObjectInputStream
        10.3 クラスを直列化可能にする方法
                10.3.1 Serializableインタフェースを実装する
                10.3.2 インスタンスレベルでローカルに定義された状態が正しく直列化されることを確認する
                10.3.3 スーパークラスの状態が正しく直列化されることを確認する
                10.3.4 equals( )とhashCode( )を必要に応じてオーバーライドする
                10.3.5 DocumentDescriptionを直列化可能にする
        10.4 直列化アルゴリズム
                10.4.1 データフォーマット
                10.4.2 簡易バージョンの直列化アルゴリズム
                10.4.3 RMI向けにカスタマイズされた直列化アルゴリズム
                10.4.4 ダイレクトコネクションの保守
        10.5 クラスのバージョン管理
                10.5.1 バージョン管理に関する2つの問題
                10.5.2 クラスの変更を直列化メカニズムが検出する方法
                10.5.3 バージョン管理機構を自前で実装する
        10.6 直列化が抱えるパフォーマンス上の問題
                10.6.1 リフレクションに依存している
                10.6.2 データフォーマットが冗長である
                10.6.3 必要以上に簡単にデータを送信してしまう
        10.7 Externalizableインタフェース
                10.7.1 ExternalizableとSerializableの比較
                10.7.2 最後の注意点

11章 スレッド
        11.1 複数のクライアント
        11.2 基本的な用語
                11.2.1 コールスタック
                11.2.2 ヒープ
                11.2.3 スレッド
                11.2.4 ミューテックス
                11.2.5 プリンタサーバのスレッド化
        11.3 スレッド化の概念
                11.3.1 個々のスレッドを制御する
                11.3.2 スレッドの動作を調整する
                11.3.3 キャッシュ管理
                11.3.4 スレッドに優先度を割り当てる
        11.4 Javaのスレッド機能
                11.4.1 ミューテックス変数が関連付けられたオブジェクト
                11.4.2 Objectクラスに定義されたスレッド操作用メソッド
                11.4.3 クラス
        11.5 デッドロック
        11.6 スレッド化とRMI

12章 スレッド化の実装
        12.1 基本的なこと
        12.2 スレッド化にあたっての指針
                12.2.1 実際に動くコードから始める
                12.2.2 一番重要なのはデータの整合性
                12.2.3 同期化ブロックの実行所要時間を最小化する
                12.2.4 コンテナクラスを使用するときの注意点
                12.2.5 コンテナをスレッド間通信の仲介役として使用する
                12.2.6 不変オブジェクトはそのままでもスレッドセーフ
                12.2.7 スレッドはいつも安全に停止すること
                12.2.8 バックグランドスレッドの優先順位は低くする
                12.2.9 何を直列化するのかに注意する
                12.2.10 スレッド化を用いて応答時間のゆれを小さくする
                12.2.11 スレッドが参照するオブジェクトの数を制限する
                12.2.12 同じ順番でロックを獲得する
                12.2.13 作業スレッドを用いてデッドロックを防ぐ
        12.3 スレッドプールを用いた拡張
                12.3.1 プールという考え方
                12.3.2 プールを定義する2つのインタフェース
                12.3.3 プールメカニズム:最初の実装
                12.3.4 SimplePoolの問題点
                12.3.5 オブジェクト生成用スレッド
                12.3.6 オブジェクト返却用スレッドの追加
                12.3.7 プールを徐々に縮小する
                12.3.8 さらなる2つの注意点
        12.4 最後に

13章 分散アプリケーションのテスト
        13.1 バンキングアプリケーションのテスト
                13.1.1 何をテストするか
                13.1.2 サーバのテスト方法
                13.1.3 バンキングアプリケーションのテスト

14章 RMIレジストリ
        14.1 なぜネーミングサービスを使用するのか?
                14.1.1 ブートストラップ
                14.1.2 ネーミングサービスはどのようなとき便利か?
        14.2 RMIレジストリ
                14.2.1 bind( )、rebind( )、unbind( )
                14.2.2 lookup( )とlist( )
        14.3 RMIレジストリはRMIサーバである
                14.3.1 レジストリのブートストラップ
        14.4 Registryの中身
                14.4.1 レジストリに問い合わせる
                14.4.2 アプリケーション固有のレジストリを起動する
        14.5 RMIレジストリの制限
                14.5.1 ディレクトリとエントリ
        14.6 セキュリティの問題

15章 ネーミングサービス
        15.1 基本的な設計、用語、要件
                15.1.1 階層化
                15.1.2 属性による問い合わせ
        15.2 我々が実装するネーミングサービスの要件
                15.2.1 利用パターン
        15.3 フェデレーションとスレッド化
                15.3.1 フェデレーション(連合)
        15.4 Contextインタフェース
                15.4.1 セットとリストを表す値オブジェクト
                15.4.2 パス、サーバ名、属性はまったく別物
                15.4.3 ヌル引数でもOK
                15.4.4 属性は単一値とする
                15.4.5 コンテキスト処理用のメソッドは別に用意する
                15.4.6 コンテキストとしてバインドされたコンテキストは属性を持たない
                15.4.7 コンテキストはサブコンテキストを直接作成できる
                15.4.8 Remoteイテレータは用意しない
        15.5 値オブジェクト
                15.5.1 AttributeSet
                15.5.2 PathとContextList
        15.6 ContextImpl
                15.6.1 NameAttributeSetPair
                15.6.2 RemoteHolder
                15.6.3 ContextHolder
                15.6.4 ContextImpl
                15.6.5 ブートストラップ
                15.6.6 バージョン2.0
        15.7 ネーミングサービスの切り替え
                15.7.1 バンキングアプリケーションを変更する
        15.8 Java Naming and Directory Interface(JNDI)
                15.8.1 Contextインタフェース
                15.8.2 JNDIをバンキングアプリケーションで使用する

16章 RMIランタイム
        16.1 リモートメソッド呼び出しの仕組みの復習
                16.1.1 RMIがブートストラップ問題を解決する方法
        16.2 分散ガベージコレクション
                16.2.1 通常のガベージコレクション
                16.2.2 ネットワークガベージの定義
                16.2.3 リース
                16.2.4 実際の分散ガベージコレクタ
                16.2.5 Unreferencedインタフェース
        16.3 RMIのロギング機能
                16.3.1 標準ログ
                16.3.2 専用ログ
                16.3.3 デバッグ用ログ
        16.4 その他のJVMパラメータ
                16.4.1 Java基本パラメータ
                16.4.2 RMI基本パラメータ
                16.4.3 トランスポート層パラメータ
                16.4.4 分散ガベージコレクタ関連のパラメータ

17章 ファクトリとアクティベーションフレームワーク
        17.1 リソース管理
        17.2 ファクトリ
                17.2.1 基本設計の見直し
        17.3 汎用ファクトリの実装
                17.3.1 基本ファクトリ
                17.3.2 既存アプリケーションの修正
        17.4 ファクトリの改良
                17.4.1 これまでの実装方法
                17.4.2 口座ロック機構の構築
        17.5 永続性とサーバのライフサイクル
        17.6 アクティベーション
                17.6.1 アクティベーションを使うために必要なコード変更
                17.6.2 起動可能なシステムの配置
                17.6.3 ActivationDesc、ActivationGroupDesc、ActivationGroupの詳細
                17.6.4 起動可能なサーバのシャットダウン
                17.6.5 rmidのコマンドライン引数
                17.6.6 アクティベーションパラメータ
        17.7 最後に


III部 より高度なトピック

18章 カスタムソケットの利用
        18.1 カスタムソケットファクトリ
                18.1.1 カスタムソケットファクトリの生成
        18.2 カスタムソケットのアプリケーションへの組み込み
                18.2.1 通常のサーバの修正
                18.2.2 起動可能なサーバの修正
                18.2.3 デフォルトのサーバの変更
                18.2.4 パラメータとの関連

19章 動的なクラスローディング
        19.1 アプリケーション配置の難しさ
        19.2 クラスローダ
                19.2.1 クラスがロードされる仕組み
        19.3 動的クラスローディングの動作原理
                19.3.1 再配置するケース
                19.3.2 複数バージョンを並列配置するケース
        19.4 クラスサーバ
                19.4.1 クラスを要求する
                19.4.2 クラスを受信する
                19.4.3 JARファイルを処理する
                19.4.4 Sunのクラスサーバ
        19.5 動的クラスローディングをアプリケーションで使う
                19.5.1 サーバ側の変更
                19.5.2 ネーミングサービスの変更
                19.5.3 クライアント側の変更
                19.5.4 動的クラスローディングを完全に無効にする

20章 セキュリティポリシー
        20.1 新たなセキュリティ上の問題
        20.2 アクセス権
                20.2.1 アクセス権の種類
        20.3 セキュリティマネージャ
                20.3.1 SecurityManagerのインストール
                20.3.2 セキュリティマネージャの動作原理
                20.3.3 java.security.debug
        20.4 セキュリティポリシーの設定
                20.4.1 3つのポリシーファイル
                20.4.2 ポリシーファイルの中身
                20.4.3 RMIでのセキュリティポリシーの使用
                20.4.4 ポリシーツール
                20.4.5 終わりに

21章 マルチスレッドクライアント
        21.1 異なる種類のリモートメソッド
                21.1.1 プリンタ型メソッド
                21.1.2 レポート型メソッド
        21.2 プリンタ型メソッドの処理
                21.2.1 最初の解決策
                21.2.2 より良い解決策
        21.3 レポート型メソッドの処理
                21.3.1 7章再考
                21.3.2 クライアント側のバックグラウンドダウンロードの実装
        21.4 以上のサンプルコードを一般化すると

22章 HTTPトンネリング
        22.1 ファイアウォール
        22.2 CGIと動的コンテンツ
                22.2.1 CGI
                22.2.2 サーブレット
        22.3 HTTPトンネリング
                22.3.1 RMIがメッセージをトンネリングする仕組み
        22.4 HTTPトンネリング用サーブレットの実装
                22.4.1 サーブレットのコード
        22.5 トンネリングの動作を変更する
        22.6 HTTPトンネリングを使用したバンキングアプリケーション
        22.7 HTTPトンネリングの欠点
        22.8 HTTPトンネリングを無効にする

23章 RMI、CORBA、RMI/IIOP
        23.1 CORBAの動作原理
                23.1.1 その他の構成要素
        23.2 バンキングアプリケーションをCORBAで実装する
                23.2.1 インタフェースの定義
                23.2.2 スタブとスケルトンの生成
                23.2.3 サーバ
                23.2.4 起動用コードとクライアントコード
        23.3 CORBAとRMIの簡単な比較
        23.4 CORBA上のRMI
                23.4.1 RMI/IIOPの欠点
        23.5 バンキングアプリケーションをRMI/IIOP対応にする
                23.5.1 CORBAによる通信

索引

Feedback

皆さんのご意見をお聞かせください。ご購入いただいた書籍やオライリー・ジャパンへのご感想やご意見、ご提案などをお聞かせください。より良い書籍づくりやサービス改良のための参考にさせていただきます。
[feedbackページへ]