JBoss Seam情報

JBoss SeamWikiMovie: Build a webapp in 10 minutesというFlushがありました。


 Understanding middlewareにWebでのオンラインセミナーが沢山ありますが、そのなかに12/07/2005に開催されたJBoss Seamセミナーもあります。後半しゃべっている方の英語が殆ど私には聞き取れません。


 Seamとは直接関係ないですが、JBossIDE for Eclipseの1.5RC2が12/12/2005にリリースされています。EclipseからのアップデートはUnable to retrieve remote reference "http://download.jboss.org/jbosside/updates/development/plugins/org.eclipse.wst.xml.core_1.0.0.jar". [Connection timed out: connect]で失敗しました。

PostgreSQL 8.1 Benchmark その2

 id:takebsdさんから,「参考になりました。」と、はてなポイントを頂きました。ありがとうございます。そのid:takebsdさんのページのブックマークを見せて頂いていたところ、VMWare上でFreeBSD 6.0をホストOSとして動作させると遅いと言う記事を見つけて調べたところhttp://www.vmware.com/community/thread.jspa?threadID=1888&messageID=7923を見つけました。FreeBSD 6.0仮想マシンフォルダのfreebsd.vmxファイルにmonitor_control.disable_apic="TRUE" を追加して、再度Benchmarkを行ってみました。但し、VMWareを昨夜5.5へアップグレードしてしまった為にFreeBSD 5.4でも設定ありとなしでBenchmarkを取り直しました。ホストOSで動作しているアプリケーションなど出来る限り同じ環境で行いました。


以下、前回と同じ方法でBenchmarkを取ってみました。

Client数 FreeBSD 5.4(設定なし) FreeBSD 5.4(設定あり) FreeBSD 6.0 FreeBSD 5.4変更ありなし(%) FreeBSD 5.4(設定なし)/FreeBSD 6.0
1 136.69 108.21 117.04 79.2 85.6
2 134.28 115.54 195.98 86.0 146.0
4 111.55 122.69 137.1 110.0 122.9
8 116.06 117.15 159.97 100.9 137.8
16 84.15 84.31 125.61 100.2 149.2
32 60.7 55.67 104.59 91.7 172.3

FreeBSD 5.4では設定があるなしでは設定なしの方が良い成績なのでFreeBSD 6.0との比較では設定なしを使いました。Client数が上がるほど差がでるのは、やはり6.0においては負荷が掛かるほどFreeBSD 5.4よりはパフォーマンスが落ちないと言うことでしょうかね。前言を翻してFreeBSD 6.0に乗換えます。

やっとChapter1を終わりました。

 Chapter1の内容。

  • Java予約語の再確認 - 大きな声で「Java is not C++」だそうです。
  • プリミティブ型の範囲
    • とくにcharは16bitで符号なしのint
    • intでもソース上では8進、10進、16進の表記が可能。
  • 配列について
    • 配列の宣言時にはヒープは確保されない。
    • 初期化の方法。
    • 多次元配列について、
    • 配列の要素へ代入出来るもの、出来ないもの。(IS-Aを考える)
    • 確保した要素数と要素へのアクセス。配列のインデックスはゼロから。
  • 変数のスコープと初期化
    • インスタンス変数は初期化しなくてもディフォルト値が与えられる。
    • ローカル変数には与えられない。


 なんか、知ってることばかりなんですが、油断せずに確認していきます。

PostgreSQL 8.1 Benchmark

 本日、FreeBSD5.4にてCVSupを行って/usr/ports/databases/以下を見てみるとpostgresql81-serverが出来ていたので早速インストールしてみた。


tmkbsd# cd /usr/ports/databases/postgresql81-server
tmkbsd# make install clean

しかし、postgresql-clientが8.0だよ〜っと言われて止まってしまうので、アンインストールしてから再度やってみた。今度は問題なくインストールは完了。続けてinitdbを行ったがエラーで止まってしまう。/usr/local/pgsql/dataがディフォルトのデータディレクトリなのだが、ディレクトリが空じゃないと怒られました。PostgreSQL 8.0をインストールしていたからで、/usr/local/pgsql/dataをディレクトリごと消してもう一度。


tmkbsd# /usr/local/etc/rc.d/010.pgsql.sh initdb

creating template1 database in /usr/local/pgsql/data/base/1 ... FATAL: could not create semaphores: No space left on device
DETAIL: Failed system call was semget(1, 17, 03600).
HINT: This error does *not* mean that you have run out of disk space.
It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be exceeded. You need to raise the respective kernel parameter. Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its max_connections parameter (currently 10).
The PostgreSQL documentation contains more information about configuring your system for PostgreSQL.
child process exited with exit code 1
initdb: removing contents of data directory "/usr/local/pgsql/data"

 kernelパラメータのSEMMNIとSEMMNSの値が低いようである。


tmkbsd# ipcs -S
seminfo:
semmap: 30 (# of entries in semaphore map)
semmni: 10 (# of semaphore identifiers)
semmns: 60 (# of semaphores in system)
semmnu: 30 (# of undo structures in system)
semmsl: 60 (max # of semaphores per id)
semopm: 100 (max # of operations per semop call)
semume: 10 (max # of undo entries per process)
semusz: 92 (size in bytes of undo structure)
semvmx: 32767 (semaphore maximum value)

同時接続180で多すぎだと思いながらも推奨値?の

To allow many simultaneous connections to your PostgreSQL server, you
should raise the SystemV shared memory limits in your kernel. Here are
example values for allowing up to 180 clients (configurations in
postgresql.conf also needed, of course):
options SYSVSHM
options SYSVSEM
options SYSVMSG
options SHMMAXPGS=65536
options SEMMNI=40
options SEMMNS=240
options SEMUME=40
options SEMMNU=120
に変更してみた。


/boot/loader.confに
kern.ipc.semmni=40
kern.ipc.semmns=240
kern.ipc.semume=40
kern.ipc.semmnu=120
と書いてリブート。


tmkbsd# ipcs -S
seminfo:
semmap: 30 (# of entries in semaphore map)
semmni: 40 (# of semaphore identifiers)
semmns: 240 (# of semaphores in system)
semmnu: 120 (# of undo structures in system)
semmsl: 60 (max # of semaphores per id)
semopm: 100 (max # of operations per semop call)
semume: 40 (max # of undo entries per process)
semusz: 92 (size in bytes of undo structure)
semvmx: 32767 (semaphore maximum value)
semaem: 16384 (adjust on exit max value)

そして再度 /usr/local/etc/rc.d/010.pgsql.sh initdbでOKでした。

ベンチマークPostgreSQLのcontribに入っているpgbenchを使う。いろいろ探してみたらPortspostgresql-contribを見つけインストール。


tmkbsd# su - pgsql
$ createdb test
CREATE DATABASE
$ pgbench -i test
creating tables...
10000 tuples done.
20000 tuples done.
30000 tuples done.
40000 tuples done.
50000 tuples done.
60000 tuples done.
70000 tuples done.
80000 tuples done.
90000 tuples done.
100000 tuples done.
set primary key...
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "branches_pkey" for table "branches"
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "tellers_pkey" for table "tellers"
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "accounts_pkey" for table "accounts"
vacuum...done.
$ pgbench -c 1 test
starting vacuum...end.
transaction type: TPC-B (sort of)
scaling factor: 1
number of clients: 1
number of transactions per client: 10
number of transactions actually processed: 10/10
tps = 104.458279 (including connections establishing)
tps = 115.436118 (excluding connections establishing)

以下はPostgreSQL 8.1をインストールする前にPostgreSQL 8.0で取った値との比較ですが、PostgreSQL8.0ではkernelパラメータを弄っていないので単純には比較できません。又、postgresql.confはlisten_address以外は変更していません。

Client数 PostgreSQL8.0 PostgreSQL8.1 単純性能比(%)
1 85.076 129.078 151.7
2 106.851 140.601 131.2
4 103.656 137.923 133.1
8 82.356 115.450 140.2
16 69.476 81.895 117.8
32 53.090 54.277 102.2


32接続くらいになると、性能アップはないようですが、それ以下ですと1.3倍〜1.5倍くらいのアップがあります。ChangeLogを読んでみるとSMPだともっと差がでるのかもしれません。SQL文を弄ったりインデックスを張ったりでチューニングするより事情が許すのであれば、さっさと8.1へ移行する方が良いということみたいです。



さて、FreeBSD 5.4とFreeBSD 6.0での対決はどうでしょうか?


http://pcweb.mycom.co.jp/articles/2005/11/07/freebsd/002.htmlにあるようにFreeBSD 6.0からはCVSupに代わりportsnapでPortsツリーを最新にした方が良いとのことなので早速


bsdtmk6# portsnap fetch
と、やってみたのですが、/usr/ports/databases/postgresql81-serverはないと怒られます。FTPftp.freebsd.orgのportsを覗いてみるとちゃんとあります。試しにCVSupを入れてPortsツリーを最新にするとやっと/usr/ports/databases/postgresql81-serverが出てきました。


 インストールして、initdbしてみるとkernelパラメータを弄らなくても出来てしまいました。ちゃんと比較するためにkernelパラメータを弄ってリブート。その後同じ手順でpgbenchで値をとってみました。

Client数 FreeBSD5.4 FreeBSD6.0 単純性能比(%)
1 129.078 66.959 51.9
2 140.601 75.084 53.4
4 137.923 72.021 52.2
8 115.450 64.642 56.0
16 81.895 51.334 62.7
32 54.277 37.290 68.7

あれ〜、FreeBSD 6.0の方が半分くらいの性能になっています。間違えたのかと何度もやり直してみましたが性能比は変わりません。なんで〜。これくらいのデータ量ではディスクIOがほとんど発生していないためにファイルシステムの恩恵には与れていないのかもしれませんが、理由はよくわかりません。誰か教えてください。一応topコマンドで他のでかいプロセスが動いているのかと思ってみましたが、そうではありませんでした。

環境:
同じWindows XP SP2のVMware 5.0上でそれぞれDisk Space 6.0GB、MEM 256MBを使った仮想マシンFreeBSD 5.4とFreeBSD 6.0をインストール。


 当面はFreeBSD 5.4でPostgreSQL 8.1を使うことにします。

JBoss Seamのサンプルアプリを試す。その4

サンプルアプリケーションBookingの続きです。

 HotelBookingActionのソースと注釈は1.3.3. Understanding Seam conversationsにあります。

以下は注釈の訳です。

    1. @Stateful アノテーションはこのクラスがステートフルなSessionBean Classだと宣言するEJBアノテーションです。ステートフルSessionBeanのスコープはデフォルトではConversation Contextとなります。
    2. @Conversational アノテーション@Beginアノテーションされたメソッドから呼ばれたLong-RunningなConversation外で動作しないコンポーネントであると言う宣言です。もしLong-Running Conversation外から呼ばれた場合はSeamJSFへifNotBegunOutcomeを返します。
    3. @LoggedIn アノテーションは作成したSeam Interceptor(LoggedInInterceptor)へ処理を依頼します。これは@LoggedIn@Interceptorと合わせて宣言されているためです。
    4. @PersistenceContext(type=EXTENDED)EJB3の拡張されたPersistence Contextで全てのEntityBeanのインスタンスが管理されたステートフルSessionBeanのライフサイクル全てに含まれます
    5. @DataModel アノテーションはListをJSFのListDataModeとして表します。これは検索画面などでのクリッカブルリストを実装するのを容易にします。ここではhotelsと名付けたConversatio変数内でListDataModelとしてページを表します。
    6. @DataModelSelectionIndex アノテーション@DataModelのプロパティに対応した行インデックスを保持するフィールド又はGet/Setのペアを定義します。
    7. @Out アノテーションはメソッドが呼ばれた後に属性値がContext変数へ他のクラスへの依存性の注入を行います。ここではhoetlと名付けられたContext変数へ各Action Listenerが呼び出され終えた後にhotelインスタンス変数の値がセットされます。
    8. @Begin アノテーションは Long-Running Conversationの開始を明示し、リクエストの終了まで作業中のConversation Contextが破棄されないようにします。それよりも作業中のウィンドウからのリクエストの全てを再び結びつけたり、Conversation非活性化までの時間が過ぎるか、@Endアノテーションされたメソッドが呼ばれて破棄したりします。
    9. @End アノテーションは作業中のLong-Running Conversationを終了させます。又作業中のConversation Contextをリスエストの終了時点で破棄します。
    10. @Removeは通常のEJBアノテーションアノテーションされたメソッドが呼ばれた後に状態を破棄すると供にステートフルSessionBeanを破棄します。Seamでは全てのステートフルSessionBeanはいずれかのメソッドに@Destroy@Removeを記述すべきです。これはSeamがConversation Contextを破棄したときにEJBのRemoveメソッドを呼びます。実際には@Destroyアノテーションの方が一般的には使い勝手がよく、どんなSeamのContextが破棄されたときの後始末にも使えます。@Destory@Removeアノテーションされたメソッドがないと状態はリークしパフォーマンスの問題に苦労します。


HotelBookingActionはホテル検索、選択、予約、予約確認の全てのAction Listenerメソッドが実装され、HotelBookingActionインスタンス変数にこの作業に関わる全ての状態が保持されています。HttpSession属性から値を受けたり、返したりするよりもシンプルできれいなコードだと思いませんか。


ひとりのユーザが複数のそれぞれがログインした独立したConversationを持つことさえ出来ます。試して下さい。ブラウザのタブで複数のホテル検索ページへログインして下さい。同時に別々のホテル予約を作成することができます。ひとつのConversationをある程度ほっておいて下さい、SeamはConversationをタイムアウトとし、状態を破棄します。


以上、http://docs.jboss.com/seam/reference/en/html/tutorial.htmlを見てきましたが、未だEJB3.0JSFも理解が出来ていないせいかもう一つピンと来ません。


原因は

  1. bijection(双方向での依存性の注入)
  2. Conversationと言う作業単位

が具体的に見えてきていないせいもあります。しかし使いこなせば強力なフレームワークになりそうです。

JBoss Seamのサンプルアプリを試す。その3

サンプルアプリケーションのBookingを見ていきます。以下もhttp://docs.jboss.com/seam/reference/en/html/tutorial.html#bookingの訳です。間違いなどあればご指摘して下さい。

1.Introduction


Bookingアプリケーションは下記の機能を備えたホテルルーム予約システムす。

    • ユーザ登録
    • ログイン
    • ログアウト
    • パスワード登録
    • ホテル検索
    • ホテル選択
    • ルーム予約
    • 予約確認
    • 予約リスト表示


BookingアプリケーションはJSFEJB3.0SeamとビューにはFaceletを使っています。又、このアプリケーションの一部はJSF、Facelet
Seam,JavaBeanやHivernate3です。


 このアプリケーションを十分試して頂くと非常に堅牢なことに気づいて頂けるでしょう。気の済むまで戻るボタン、ブラウザのリフレッシュ、
複数のウィンドウ開いたり、出鱈目なデータを入れたりしてもアプリケーションをクラッシュさせるのが難しいと気づいて頂けるでしょう。
このアプリケーションを完成するのにテストやバグ修正で数週間費やしたとお考えですか?実際はそうではありません、
Seamは堅牢なWebアプリケーションを容易に作成でき、堅牢さはあなたが書かなければならないコードに含まれたりSeamが自動的に不可します。


サンプルアプリケーションのソースコードを見てアプリケーションがどのように動作しているか見て、堅牢さをもるために状態管理を記述式にすること
や組み込まれた妥当性検査がどうなのか意見を述べて下さい。


2. Overview of the booking example



 プロジェクトの構成は前のサンプルアプリケーションregistrationとまったく同一です、インストール、デプロイはSection 1.1 Try the examplesを参考にして下さい。
アプリケーションをスタートしhttp://localhost:8080/seam-booking/へブラウザでアクセスして下さい。

 10のクラス(プラス6つのSessionBeanのLoacal Interfaceと一つのAnnotation Interface)を使用してこのアプリケーションを実装しています。6つのSessionBean Action Listenerは
以下にリストしたビジネスロジックを全て含んでいます。

    • BookingListActionは現在ログイン中のユーザの予約済みの記録を取出します。
    • ChangePasswordActionは現在ログイン中のユーザのパスワードを変更します。
    • HotelBookingActionはこのアプリケーションの中心的な機能を実装していす。ホテルの部屋を検索、選択、予約、予約確認です。この機能は対話的に実装しありますのでこのアプリケーションの中で最も興味深いクラスです。
    • LoginActionはログインデータの妥当性検証をログインユーザのデータを取出します。
    • LogoutActionはログインセッションを終了させます。
    • RegisterActionは新規にシステムユーザを登録します。



3つのEntityBeanがアプリケーションのデータ永続性ドメインへ実装されています。

    • Hotel EntityBeanはホテルを表します。
    • Booking EntityBeanは予約記録を表します。
    • Use EntityBeanはホテル予約を行うことができるユーザを表します。


3. Understanding Seam conversations



 私たちはソースコードを見て頂たいのです。このチュートリアルで際立った機能をに注目してみましょう。ホテル検索、選択、予約、予約確認です。ユーザの視点から見ると、これはひとつの連続的な作業の単位、Conversationです(対話と言う訳は合ってないような....)


 ほとんどのWebアプリケーションの設計はConversationに相当する最も良い機構がありません。Conversationと状態管理との統合は大きな問題を引き起こすからです。通常Java Webアプリケーションは2つの技術を組み合わせたものです。最初に、ある状態はHttpSessionへ投げられ、次に永続的な状態は全てのリクエストの後にDatabaseを書換え、そして新しいリクエストが始まるときにDatabaseから状態を再構築します。


Databaseが最も拡張性に欠けるアプリケーション層であることが、しばしば容認出来ないほどの拡張性の欠如の原因になります。全てのリクエストに対しDatabaseとの余分な通信に起因する待ち時間が加わることも問題です。この助長な通信を無くすためにJavaアプリケーションはリクエスト間でよくアクセスされるデータをキャッシュする方法を導入します。キャッシュを無効にするポリシーがユーザが使用し終わったデータのかわりにLRU Policyが採用されているため、このキャッシュはどうしても非効率です、更に沢山の平行したトランザクション間で共有されるため、私たちの言うDatabaseと一貫性のあるキャッシュを保つことは多くの問題にぶつかります。


 HttpSessionでの状態を保つことを考えてみましょう。注意深くプログラムすればセッションデータのサイズをコントロールできるかもしれません。それはブラウザで、想定された以外の自由なナビゲーションを許すことを前提にすると、言われているよりはずっとむづかしいと思います。しかし私たち(私に起こったことですが)はシステム開発の途中で突然、ユーザは複数のConversationを同時に行うことが出来るようにシステムに求めていることを思いついたのです。同時に行われているそれぞれのConversationを分離するメカニズムを開発し、ユーザがブラウザのウィンドウを閉じたり、ブラウザのタブがアクティブにされないなどでConversationの状態が破棄されたことを明確にすることによってフェイルセーフ機能を盛込みます。


 こちらの方が良い方法です。


SeamはConversation Contextという構成を導入しています。これはContextに安全にConvarsationの状態を保存出き、明確なライフサイクルもつことを確実にします。より良いことに、Conversation Contextがユーザが現在作業しているデータを自然にキャッシュとしているため、DatabaseとApplication Server間でひっきりなしにDataを送ったり受取ったりする必要がありません。


 通常Conversation Contextに保存しているコンポーネントはステートフルなSessionBeanです(もちろんEntityBeanもJavaBeanもConvaersation Context内に保存できます)。JavaコミュニティにはステートフルSessionBeanが拡張性を犠牲にすると言う言い伝えがあります。これは1998年にWebFoobar 1.0がリリースされた頃は真実だったかもしれません。しかし今は違います。例えばJBoss 4.0のようなアプリケーションサーバであればステートフルSessionBeanの状態を複製する洗練されたメカニズムを持っています(例えばJBoss EJB3コンテナは粒度の細かいレプリケーションを行い、それらのBeanの属性値が変更された場合に複製されます)。なぜステートフルBeanは非効率なのかという古くからの議論はHttpSessionに対するものと同じです、状態をビジネス層のステートフルSessionBeanからWebセッションへ移行することはパフォーマンスを上げるための方向を信じれない方へ向かわせます。ステートフルBeanを間違った使い方をしたり、間違ったものをそれらに使ったりして拡張性のないアプリケーションを書くことは可能です。しかしそれらを決して使わないと言う意味ではありません。Seamは安全な使用モデルへあなたを導きます。ようこそ2005年へ。


 大げさに言うのはもう止してチュートリアルへ戻りましょう。


さあ、サンプルアプリケーションBookingでConversationに関する永続性データを自然にキャッシュとして用いるConversationスコープなステートフルSessionBeanをどのように使っているかみてみましょう。下記のコード(省略してますのでオリジナルを見てください。)は少々長いです。しかし、Conversationのいろいろな段階を実装したスクリプト化したアクションのリストだと考えると非常に理解し易いでしょう。物語だと思ってクラスを上から下へ読んで下さい。

就職用面接対策

 先月仕事探しのSiteに登録したのですが、こちらからは積極的にレジメを送ったりとかはしていませんでした。本日Amazon.comから下記が届きました。

Conducting the J2Ee Job Interview: It Manager Guide for J2EE With Interview Questions (It Job Interview Series)

Conducting the J2Ee Job Interview: It Manager Guide for J2EE With Interview Questions (It Job Interview Series)

Conducting the Java Job Interview: IT Manager Guide for Java with Interview Questions (It Job Interview Series)

Conducting the Java Job Interview: IT Manager Guide for Java with Interview Questions (It Job Interview Series)


 面接時に聞かれそうな技術的な質問と無難な答えの本です。以前MS SQL Database Adminの面接を受けたときに何の準備もしていかなかったので、


「Clustered Indexについて教えてください。」とか

「第二正規化と第三正規化について答えて下さい。」とか

いきなり(そりゃ雇う側なら聞くわな〜)聞かれて、日本語なら何とか答えられるが、英語となるとしどろもどろとなり撃沈していまったので今回は対策して行きます。