境界を越える: 継続とWeb開発、そしてJavaプログラミング

プログラマーにとってはステートフル・モデルが、ユーザーにとってはステートレス

『境界を越える』シリーズは、Java™ではない言語が大きな問題をどのように解決しているかを学び、そうした解決方法が今日のJava開発者にとって何を意味するのかを考えます。今回の記事では、SmalltalkのSeasideのようなフレームワークの背景技術である、継続(continuation)を探ります。継続サーバーを利用すると、ステートレスであることに特有なスケーラビリティーを諦めることなくステートフルなプログラミング・モデルを実現できるため、Webアプリケーションの構築がずっと容易になるのです。

Bruce Tate (bruce.tate@j2life.com), President, RapidRed

Bruce TateBruce Tateは父であり、マウンテンバイク乗りであり、カヤック乗りであり、そしてテキサス州オースチンに住んでいます。Joltを受賞した『Better, Faster, Lighter Java』を含め、ベストセラーとなった3冊の著書を執筆しています。最近、『Spring: A Developer's Notebook』を発刊しました。彼はIBMに13年間在籍した後、J2Life, LLC社を設立し、Java技術とRubyに基づく軽量開発戦略とアーキテクチャーを専門としたコンサルティングを行っています。



2006年 3月 21日

Web開発は一見魅力的に見えますが、実際に行ってみると手痛い思いをさせられるものです。JavaのWeb開発者は非常な努力をしてステートレス・モデルを提供しようとしますが、その結果得られるパフォーマンスやデプロイの容易さは、確かに努力に見合うものです。この記事では、そうした手法とは劇的に異なる、『継続サーバー(continuation server)』と呼ばれるWeb開発手法について解説します。継続サーバーを利用すると、ステートレスであることに特有なスケーラビリティーを諦めることなくステートフルなプログラミング・モデルを実現できるため、Webアプリケーションの構築がずっと容易になるのです。

このシリーズについて

この、『境界を越える』シリーズでは、著者であるBruce Tateが、「今日のJavaプログラマーは、他の手法や言語を学ぶことから多くを得ることができる」という概念を押し進めます。プログラミングの世界の様相は、あらゆる開発プロジェクトにとってJavaを選択することが明確に最善であった頃から変わってきています。他のフレームワークもJavaフレームワークと同じ構築形態をとりつつあり、また他の言語での概念を学ぶことによって、それをJavaプログラミングに生かすこともできます。皆さんが書くPython(あるいはRubyやSmalltalk、その他何であれ)コードによって、皆さんのJavaコーディングに対する取り組みも変わる可能性があるのです。

このシリーズでは、Java開発とは大幅に異なりながら、同時にJava開発に直接応用できるプログラミング概念や手法を紹介します。場合によると、こうした技術を利用するためには統合が必要かも知れません。また場合によると、ここで紹介する概念を直接応用することもできます。他の言語やフレームワークが、開発者やフレームワーク、Javaコミュニティーでの基本的な手法にまで与えうる影響に比べると、個々のツールはそれほど重要ではありません。

Webの台頭

1990年代の半ば、業界全体がWeb開発に向かい始めた頃、ソフトウェア開発者は陶酔状態にありました。それまで私達が構築していたクライアント・サーバー・アプリケーションは、ターミナルとホストの組み合わせよりはユーザーに使いやすいものでしたが、幾つかの問題があったのです。

  • 多くの場合、パフォーマンスが貧弱。ターミナル・ベース開発の利点は、コミュニケーションのコストがプログラミング・モデルによって制限できることです。こうした制限がいったん無くなると、今度は単純な分散アプリケーションを構築するためにも、帯域幅やツール、スキルなどが足りなくなりました。
  • アプリケーションに移植性がない。大部分のクライアント・サーバー開発環境は、使われるハードウェア環境やソフトウェア環境に直結していました。
  • アプリケーションがデプロイしにくい。潜在的には、何千ものクライアントを独立に管理しなければなりません。
  • 最大コストが見えない。後処理(post-production)のコストが激増するため、デプロイこそが最大の制限となってしまいます。

それでもクライアント・サーバー・コンピューティングは前進を続けました。多くの場合、企業はソフトウェアやハードウェアのコストが低いことを理由に予算決定を行ってしまい、実稼働後に管理コストが激増することに驚きましたす。1995年には、クライアント・サーバー・モデルには劇的な改善が必要となりました。そしてそうした改善が、正に実現しそうに見えたのです。

Web開発の登場

1990年代の中頃、Web開発は爆発的な発展を遂げました。Java言語の登場により、分散Webアプリケーションを開発できると同時に、クライアント・サーバー型における最も深刻な問題を、新しい機能によって解決できたのです。こうした機能は次のようなものです。

  • コミュニケーションの制限。リクエスト/レスポンスというWebモデルは、ターミナル・ベース開発の特徴を全て備えています。ユーザーがフォームに入力してリクエストすると、レスポンスが得られます。クライアントとサーバー間での頻繁なコミュニケーションがなくなり、パフォーマンスが改善されました。
  • 何も共有しないアーキテクチャー。サーブレット・ベースのプログラミングは、ステートレスであることができます。これはつまり、1つのサーブレットで任意クライアントをサービスできること、また固定したサーブレット・プールがあれば、さらに多くのユーザーをサービスできることを意味します。ユーザー毎にサーブレットを予約する必要はありません。そのため、パフォーマンスがさらに改善されます。
  • 共通標準を使うクライアント。全クライアントに共通のブラウザーをデプロイすれば、1つのインターフェースを構築するだけで、ほとんど全てのクライアントに到達できます。多くのブラウザー・クライアントをサポートしようとすると問題が起きがちですが、ネイティブのユーザー・インターフェース・ライブラリーをサポートすることによる困難に比べれば楽なものです。おかげで、移植性に関する多くの問題はなくなりました。
  • より良いデプロイメント・モデル。共通クライアントとしてブラウザーを使用できるため、ディストリビューションがずっと単純になります。企業は、何台かのインターネット・サーバーにアプリケーションをデプロイすれば、それを企業全体に渡って共有することができます。ネットワーク・アーキテクチャーでは多くの場合、複数のサーバーに渡ってリクエストを共有することができます。そのため、単にもう1台のサーバーを追加するだけで、能力を増強することができます。またクライアント側のデプロイは、共通クライアントとして正しいブラウザーが使われていることを確認するだけです。つまり管理はずっと単純になったのです。

パフォーマンスやスケーラビリティー、管理容易性、移植性など、すべてが改善されるため、インターネット革命が加速されました。しかし同時に、大きな妥協を迫られることになったのです。

理想ではない

『ステートレス』という単純な言葉によって、システムから開発者へと、大きな負荷が移ったのです。確かに、その成果そのものには議論の余地はありません。ユーザー毎に1つのサービスやサーブレットを維持する必要はないため、素晴らしいスケーラビリティーが得られます。その代わり、状態を管理する責任が、プログラミング言語から開発者へと移ったのです。今日でのWeb開発は、一連のステートレス・リクエストとして考えることができます(図1)。

図1.Webアプリケーションはリクエストとレスポンスの対で構成される
Webアプリケーションはリクエストとレスポンスの対で構成される

このモデルでは、ブラウザーがしっかりと制御を握っています。アプリケーションは、ブラウザーが行うリクエストに対してのみ応答します。このモデルはリクエストが小さく独立している場合にはうまく行きますが、マルチパート・アプリケーションを駆動するアプリケーションでは、情けないほど失敗します。その最も一般的な例として、オンライン・ショッピングがあります。Submitボタンを2回押すと、多くの場合は同じアイテムを誤って2つ注文してしまうことになります。そのまま店を出て2週間後に戻ると、(そんな振る舞いは想定していないのに)同じアイテムが2つ、カートに載っているかも知れません。

通常、ユーザーがステートフルな経験をするのは、ある対話動作に関連する全データがセッションに置かれ、そのユーザー・セッションが、クライアント側のクッキーや隠しフィールド、URL変数などにマーキングされた場合です。そうした場合には下記のような動作を、新しいリクエスト毎に、この順序で行う羽目になります。

  • ユーザーのIDをクライアントから取得する
  • セッションから対話状態を回復する
  • ユーザーのリクエストを処理する
  • レスポンスを構築する
  • 対話状態をセッションに保存する
  • レスポンスをユーザーに送る

ここでは問題を非常に単純化しましたが、これは、ステートレス・モデルを使ってステートフルなアプリケーションをシミュレートすると、さらに問題が深刻になるためです。最も根本的な問題は、Web開発と同じくらい歴史の古い問題、つまり「戻る」ボタンをどう処理するか、という問題です。


古い問題に対する新しい答え

プログラマーにとってはステートフル・モデルでありながら、ユーザーにとってはステートレスとなるWeb開発が可能なことを知ると、皆さんはショックを受けるかも知れません。しかし実際には、Paul Grahamが『Hackers and Painters』(参考文献)の中で、既に1995年のViaWebにおいて、この基礎となっている手法を紹介したことを述べています。この手法では、『継続(continuation)』というプログラミング制御構造を使うのです。

この基本的な考え方は、「プログラミング・フレームワークが、アプリケーションの状態をリクエストの前にロードし、また各リクエストの後に保存するようにする」ということです。この「継続」を、まずRubyプログラミング言語で見て行くことにします。

Rubyの例

この記事の説明に合わせてコーディングしたい方は、Rubyをインストールしてからirbをタイプしてください。> という文字の後に下記のコマンドをタイプして、loopというメソッドを定義します(リスト1)。

リスト1.loopメソッドを作る
irb(main):001:0> def loop(interrupt)
irb(main):002:1> for i in 1..10
irb(main):003:2> puts "Value of i: #{i}"
irb(main):004:2> callcc {|c| return c} if i == interrupt
irb(main):005:2> end
irb(main):006:1> end
=> nil

loopメソッドには、interruptという1つのパラメーターがあります。forループで1からiまでループし、iの値を出力すると・・・。怪しげなcallccステートメントは、『継続で呼ぶ(call with continuation)』を意味しています。継続というのは、ある瞬間にプログラムを凍結した場合のプログラムの状態だと思ってください。Rubyは括弧の中にあるコード・ブロックを呼び、継続オブジェクトを渡します。括弧の中にあるコードは閉包(closure)であり、単純にcallccに渡されるコード・ブロックです。最終的な結果としては、callccが実行の状態をキャプチャーし、その結果をcに保存します。そうすると、ループの任意ポイントでこのメソッドを呼んで実行に割り込みをかけ、プログラムの状態をキャプチャーすることができます。そしてその後で、実行を再開することができます。

では、このメソッドを何度か実行してみましょう(リスト2)。

リスト1.ループ・メソッドを実行する
irb(main):007:0> cont = loop 5
Value of i: 1
Value of i: 2
Value of i: 3
Value of i: 4
Value of i: 5
=> #<Continuation:0x2b5a358>
irb(main):008:0> cont.call
Value of i: 6
Value of i: 7
Value of i: 8
Value of i: 9
Value of i: 10
=> 1  10
irb(main):009:0> cont = loop 8
Value of i: 1
Value of i: 2
Value of i: 3
Value of i: 4
Value of i: 5
Value of i: 6
Value of i: 7
Value of i: 8
=> #<Continuation:0x2b562f0>
irb(main):010:0> cont.call
Value of i: 9
Value of i: 10

このコールを実行する度に、継続はどこで実行が中断されたかを拾い上げます。つまり継続を使用するWeb開発フレームワークは、各リクエストの処理後に継続をキャプチャーし、それにIDを付けてセッションの中に保存できるのです。また新しいリクエストが来た場合には、フレームワークはユーザー・データを保存するために使用した手法と同じ手法を使って、その新しいリクエストの処理前にセッションから継続を回復することができます。

長所と短所

継続サーバーによる手法を利用すると、様々な面で、多くのものを同時に手に入れることができます。つまりステートフルなプログラミング・モデルと、ユーザーにとってはステートレスなパフォーマンスを同時に実現することができます。この方法の利点は、次のように要約することができます。

  • リクエストとリクエストの間は、確実にステートレスになります。このフレームワークはURL内の個々の継続を識別でき、その継続をセッションの中に保存することができます。
  • ステートフルなプログラミング・モデルが実現します。このフレームワークは、任意の時に、任意の継続を回復することができます。ユーザーが2度目にフォームをサブミットする場合には、継続は、より早い時点で処理を行うことができます。
  • 継続はビジネス・ルールによって無効化できるため、フォームが2度サブミットされるのを容易に防ぐことができます。
  • 「戻る」ボタンのサポートを無料で投げることができます。どの時点の実行状態も正確に分かるため、もしユーザーが「戻る」ボタンを押した場合には、このフレームワークは単純に適当な継続を回復するだけです。
  • 共有リソースが無いため、スレッド化が容易になります。リソース競合が無いということは、スレッド化に伴う問題の大部分は無くなるということです。

継続によって、Web開発モデルは劇的に単純化されます。継続を利用すると、Webアプリケーションを、より多くのユーザー情報を提供するための一連のリクエストを持つアプリケーション、と考えることができます。図2は、継続を利用して改善されたアプリケーション・フローを示しています。ユーザーがアプリケーションを開始すると、Webブラウザーが制御を握ります。アプリケーションは、バラバラなリクエストをバラバラな順序で処理するのではなく、統一された形で、方向性を持ってユーザーと対話できるのです。

図2.継続によってアプリケーション・フローが自然になる
継続によってアプリケーション・フローが自然になる

上位レベルでの抽象化の例に漏れず、継続にも欠点があります。そしてこうした欠点は、継続に依存する手法全体にも影響を与えます。つまり継続サーバーは、次のような一般的な問題を解決しなければなりません。

  • 継続は高価である。容易にセッションにデータを置けるということは、「誰もが、より多くのデータをセッションに置こうとする」ということを意味しています。フレームワークの設計者は、『部分的継続(partial continuation)』と呼ばれる手法を使うことでコストを削減することができます。(部分的継続では、フレームワークは継続のうち、アプリケーション特有の部分のみを保存します。)
  • URLが醜悪。ほとんどの継続サーバーは、醜悪な識別子を継続に付加します。
  • ユーザーから見た動作が変わってしまう。継続サーバーが一般的に使用されるようになると、ユーザーから見た動作が異なってきます。「戻る」ボタンは実際に動作するため、一部のユーザーは混乱します。例えば、買い物カゴに何かを入れた後に「戻る」ボタンをクリックした場合、皆さんはアプリケーションがそれを買い物カゴから出してしまうことを期待するでしょうか。

全体として見ると、継続は大きな前進であり、近い将来には、継続サーバーが普通に実装されるようになるでしょう。では今度は、他の言語での実装を少し見てみましょう。その後で、Javaに近いところで何が起きているかを示すことにします。

他の言語で実装する

実は、幾つかの言語が継続ベースの手法を持っています(これについての詳細は、参考文献のリンクを見てください)。最も一般的なものとして、LispやRubyがあり、そして何よりもSmalltalkがあります。

  • Seaside:最も一般的な継続サーバーであるSeasideは、Avi BryantによってSmalltalkで実装されています。劇的に異なり、そして驚くほど生産性の高いWeb開発フレームワークを理解するためには、Seasideを知る必要があります。それによって皆さんのJavaプログラミングへの取り組み方も変わるはずです。
  • Iowa:RubyのIowaフレームワークもAvi Bryantによって作られたものであり、Web Objectsに着想を得ています。現在は別のサポート・メンバーによって、Rubyで使用され、またRubyで維持管理されています。
  • Wee:Weeフレームワークも継続サーバーの特徴を数多く備えたRubyフレームワークですが、ネイティブ言語での継続は使用していません。
  • ViaWeb:ViaWebはLispで継続を使用することによって、1995年には他の競争相手よりも高い生産性を誇っていました。
  • Continuity:ContinuityはPerlベースの継続サーバーです。Perl 6はネイティブで継続をサポートする予定です。

ここには挙げていないものも幾つかあります。現時点では、大部分の継続サーバー実装は継続をサポートする言語で行われていますが、これらの言語は主流ではありません。しかしこれだけでは、現在起きていることの全体像を正確に説明したことにはなりません。


Java言語における継続サーバー

Java開発者は、Webフレームワークの構築において継続ベースの手法が持つ力を次第に認識するようになっていますが、Java言語はネイティブの継続をサポートしていません。言語で継続がサポートされていない場合には、選択肢が限られます。つまり継続をシミュレートする、既存言語に継続を追加する、あるいは新しい言語を選択する、などの中から選ぶしかありません。様々なJavaフレームワーク(参考文献)では、下記のような手法を使っています。

  • 継続をシミュレートする。一部のJavaフレームワークでは、別の手法を使って実行の状態をキャプチャーします。Lakeshoreではスレッドを使い、SpringのWeb Flowは状態マシンを使っています。(Web Flowについては、この記事の後の方で説明します。)
  • 別の言語を選択する。この場合は、Java仮想マシンの上に別の言語を持ちます。Cocoon 2はこの手法を、Rhinoを使って実現しています。(RhinoはJavaScriptをサポートする仮想マシンですが、Javaもサポートしています。)
  • 継続を実装する。Jetty 6サーブレット・コンテナーやRIFE、WebWorkなどは、この手法を使っています。

ネイティブの継続をシミュレートする

実行状態をキャプチャーするために、必ずしも継続を使用する必要はありません。サスペンドされたスレッドや状態マシンは、どちらも実行状態をうまくキャプチャーすることができます。スレッドによる方法では、単純に既存スレッドをフリーズし、保存します。この方法によるパフォーマンスはステートレスではないため、この方法はやや限定的です。つまり実際にはユーザー毎に別のスレッドを使うのです。

しかし、『状態マシン』の方は、なかなか素敵な方法です。状態マシンというのは、状態から状態への遷移がよく定義されたプログラムです。継続サーバーの影響を最も大きく受けている一般的なJavaフレームワークは、何と言ってもSpringのWeb Flowです。Web Flowは、ユーザー・インターフェースのページ間でのナビゲーションを、状態マシンとしてモデル化しています。Web Flowは、フローをJavaオブジェクトとしてモデル化できますが、通常はXMLを使ってフローを記述します。Web Flowのチュートリアル(参考文献)から引用した、リスト3のフロー表現を考えてみてください。

リスト3.Web Flowでのフロー表現
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE webflow PUBLIC "-//SPRING//DTD WEBFLOW//EN"
        "http://www.springframework.org/dtd/spring-webflow.dtd">

<webflow id="myFlow" start-state="displayForm">

    <view-state id="displayForm" view="form">
        <entry>
            <action bean="myFlowAction" method="setupForm"/>
        </entry>
        <transition on="submit" to="processSubmit">
            <action bean="myFlowAction" method="bindAndValidate"/>
        </transition>
    </view-state>

    <action-state id="processSubmit">
        <action bean="myFlowAction"/>
        <transition on="success" to="finish"/>
    </action-state>
        
    <end-state id="finish" view="success"/>

</webflow>

このフローには、displayFormとprocessSubmit、finishという3つのコア状態があります。このフローは、1つの状態から次の状態へとマシンを遷移させるアクションを定義しています。例えば、サブミットによって、状態はdisplayFormからprocessSubmitへと遷移します。Web Flowは、通常のモデル・ビュー・コントローラーというレベルよりも上で動作します。フォームの表示には、様々なビュー技術を使うことができます。

1つの状態から次の状態へと遷移すると、フレームワークは現在の状態を、全てのインスタンス変数と共に自動的にキャプチャーします。「戻る」ボタンのサポートと、ステートフルなプログラミング・モデルは、他の継続サーバーが提供するものと同じです。この方法ではネイティブの継続は使用しませんが、継続サーバーの利点の多くを利用できる上、さらに下記に挙げるような利点があります。

  • パーシスタンス。コール・スタック全体をキャプチャーすることはできませんが、現在の実行状態をキャプチャーすることができ、しかも現在の状態を永続させることさえできます。
  • ワークフローのようにライフの長いフロー。状態は対象のコール・スタックに依存しないため、この方法は持続期間の長いワークフローのようなものに対して、より安定しています。
  • ツール。XML用のツールを作ることは比較的容易です。

別の言語を使う

Cocoonでは、JVMにプラグイン可能なJavaScript仮想マシンであるRhinoを使用しています。Cocoonコントローラーは改造版のRhinoを使って継続を表現しているため、Cocoonを使うとコントローラー・ロジックをJavaあるいはJavaScriptで表現することができます。Cocoonのチュートリアル(参考文献)から引用したリスト4のアプリケーションを考えてみてください。

リスト4.Cocoonを使う
  try {
    if (operator == "plus")
      cocoon.sendPage("result.html", {result: a + b});
    else if (operator == "minus")
      cocoon.sendPage("result.html", {result: a - b});
    else if (operator == "multiply")
      cocoon.sendPage("result.html", {result: a * b});
    else if (operator == "divide")
      cocoon.sendPage("result.html", {result: a / b});
    else
      cocoon.sendPage("invalidOperator.html", {operator: operator});
  }
  catch (e) {
    cocoon.sendPage("error.html", 
      {message: "Operation failed: " + e.toString()});
  }

リスト4のsendPageメソッドに注意してください。このメソッドは、ユーザーにページを送り返します。通常は、「戻る」ボタンをサポートしたり、ユーザー・データをセッションに保存したりするために面倒な繰り返しコードが必要ですが、ここにはそうしたコードがありません。そうしたコードはすべて、Cocoonのフレームワークの中にカプセル化されています。

継続を実装する

RIFEフレームワークは独自の継続を実装しており、またWebWorkフレームワークはRIFEの継続実装を使用しています。またJetty 6にもJavaでの継続実装が含まれています。リスト6はRIFEのチュートリアルからの引用ですが、数当てゲームのサンプルです。

リスト5.RIFEの例
while (mGuess != answer) {
  print(template);
  pause();
  guesses++;

  if (answer < mGuess) {
    template.setBlock("indication", "lower");
  } else if (answer > mGuess).{
    template.setBlock("indication", "higher");
  }
}

この例では、pause() というメソッドが継続をキャプチャーし、ユーザーがアクションを取れるようにテンプレートをユーザーに送り返します。RIFEを利用すると継続が単純になり、日常的なWeb開発で継続が利用しやすいものとなります。


近い将来

継続は、Web開発フレームワークにおける真の進歩を表しています。継続を利用することによって、生産性を一層高めることができます。また、相互に関連しない何百ものサーブレットを使う代わりに単純なJavaコードとしてWebアプリケーションを表現できるため、アプリケーションは読みやすくなり、また維持管理も容易になります。

Web開発における新たな進歩によって、継続という手法がさらに重要になりつつあります。リクエストとレスポンスによる伝統的なモデルを使ってWebページ全体をフェッチする代わりに、AjaxアプリケーションはWebページの小さな部分のみを非同期でフェッチし、その結果を既存ページの中に織り込むことができます。しかしAjaxアプリケーションでは多くの場合、アプリケーションの応答を保つために、また状態の追跡をコード化しやすくするために、ユーザーとの間の接続を長期間維持する必要があります。つまり接続されたユーザーそれぞれに対してリソースを保持する必要があるため、これではステートレスなプログラミング、という本来の目的が意味をなさなくなります。継続を使用すれば、状態を継続の中に保存し、その状態をオンデマンドで回復できるのです。

継続ではリソース消費が増加するという問題は、ハードウェアが改善されるにつれ、近い将来には致命的でなくなるはずです。根本的な大修正を行わない限り、現在のWeb開発フレームワークは複雑すぎます。またAjaxによって、Web開発は一層複雑になります。こうした要因が集まると、継続サーバーも受け入れやすいものとなります。今後2年以内に、新たなWeb開発では大部分の場合、何らかの継続サーバー、あるいは継続のシミュレーションを使うようになるでしょう。

次回は、領域特有の言語と、そうした言語がRuby on Railsで果たす役割について説明します。そしてそれらを基に、Javaプログラミングでの領域特有言語で何が起きているかについて説明して行く予定です。

参考文献

学ぶために

  • Ben Galbraithが「Java Web Server: Jetty 6.0 Continuations for Ajax Architectures」の中で、継続ベースの手法に影響を与えているAjaxでの動きについて説明しています。
  • Bruce Tate著による記事、「Secrets of lightweight development success, Part 8: Seaside」(developerWorks, 2005年11月)は、最も一般的で重要な継続サーバーを紹介しています。
  • Paul Graham著によるHackers & Painters (2004年O'Reilly刊) の中にある数多くのエッセイの1つは、継続を使い始める際の経験について触れています。
  • Apache Cocoon Projectのためのユーザー・ドキュメンテーションのうち、Advanced Control Flow - Continuationsの部分は、Cocoonでの継続について説明しています。
  • Rubyでの継続サーバーであるIowaを知るために、チュートリアル、What Is Iowaを調べてみてください。
  • RIFE/continuationsはRIFEのサブプロジェクトであり、純Javaでの継続サポートを、汎用ライブラリーとして利用できるようにすることを目的としています。
  • Experimental continuations in WebWorkを調べてみてください。WebWork Java Webアプリケーション開発フレームワークは、その新しい継続実装のためにRIFEの継続を使っています。
  • チュートリアル、Spring Web Flow Quick Startは、Spring Web Flow 1.0を素早く使い始めるために役立つでしょう。
  • Bruce Tate著によるBeyond Java (2005年O'Reilly刊) は、Javaの台頭と高原状態について、また、一部のニッチ領域でJavaに対抗しうる技術について解説しています。
  • Java technologyゾーンには、Java開発者のための資料が他にも豊富に用意されています。

製品や技術を入手するために

  • RIFEは革新的なフレームワークであり、継続の他、動的言語で一般的な多くの手法を利用しています。
  • Spring's Web Flowは、汎用のフロー・エンジンであり、Webアプリケーション内でのページ・フローの定義と実行に焦点を当てています。
  • Lakeshoreは、JavaベースのWebコンポーネント・フレームワークであり、Seaside 2とBorges Rubyフレームワークから大きな影響を受けています。
  • Jetty 6はJavaでのサーブレット・コンテナーであり、継続をサポートしています。
  • Seasideは最も一般的な、そして影響力のある継続サーバーです。
  • WeeもRubyの継続フレームワークです。
  • Continuityは、Perl用の継続ベースのWebプログラミング・フレームワークです。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Java technology, Open source, Web development
ArticleID=219189
ArticleTitle=境界を越える: 継続とWeb開発、そしてJavaプログラミング
publish-date=03212006