- PR -

タグライブラリの初期化について

1
投稿者投稿内容
みやも
ベテラン
会議室デビュー日: 2002/04/22
投稿数: 74
投稿日時: 2002-12-26 15:52
お世話になります。

[質問]
タグハンドラ(Tag実装クラス)のフィールドの初期化はどこで行うのが適切でしょうか?
release()というのがそれっぽいのですが、
これはコンテナから呼ばれることは仕様で保障されているのでしょうか?

ご存知でしたら教えてください。
よろしくお願いします。


[補足]
Tomcatを使って開発を行っているのですが、
先日4.0.4→4.1.12にバージョンアップしてみたところ、
それまで正常に動いていたカスタムタグが妙な動きをしはじめました。
調べてみると、4.1.?からパフォーマンス改善のためにタグハンドラの
プーリングが使われているようでした。
で、初期化はしないとねーということで初期化したいのですが、
どこですべきか、どうもはっきりしません。



[ メッセージ編集済み 編集者: みやも 編集日時 2002-12-26 15:53 ]

[ メッセージ編集済み 編集者: みやも 編集日時 2002-12-26 15:57 ]
ayum
常連さん
会議室デビュー日: 2002/03/28
投稿数: 44
お住まい・勤務地: 東京
投稿日時: 2002-12-26 16:08
release()メソッドはJSPコンテナがタグリブを実行する際、
最後に必ず呼ばれることになっているので
フィールド値の初期化はここで行ってあげればいいと思います。
release()を実装する際、
最初にsuperのrelease()は呼んであげた方が無難でしょうね。
タグリブの動き等に関してはピアソン・エデュケーションから出てる
『アドバンスドJavaServerPages』という本が参考になります。

http://www.amazon.co.jp/exec/obidos/ASIN/4894714744/qid=1040886453/sr=1-3/ref=sr_1_2_3/249-7995313-0177118
みやも
ベテラン
会議室デビュー日: 2002/04/22
投稿数: 74
投稿日時: 2002-12-26 17:19
ayumさん、回答ありがとうございます。

『アドバンスドJavaServerPages』見てみました(つん読状態でした。。。)。
11ページのシーケンス図がわかりやすかったです。
最後にrelease()が呼ばれるわけですね。

でも試してみると、なぜかrelease()が呼ばれません。
Tomcatのせいかも?と調べてみるとバグデータベースで以下を見つけました。

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13392

(私の微妙な英語力では)release()はGC時に呼ばれるもので、
実行時に毎回呼ばれないのは正しい動作だ。TomcatはこれでOK。
という風に読み取れました。

relase()はタグハンドラの実行毎に呼ばれるものではないのでしょうか?
だとすると、初期化はどこですべきものでしょうか?
ayum
常連さん
会議室デビュー日: 2002/03/28
投稿数: 44
お住まい・勤務地: 東京
投稿日時: 2002-12-26 17:38
引用:
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13392

(私の微妙な英語力では)release()はGC時に呼ばれるもので、
実行時に毎回呼ばれないのは正しい動作だ。TomcatはこれでOK。
という風に読み取れました。

relase()はタグハンドラの実行毎に呼ばれるものではないのでしょうか?



・・・なるほど、確かにそう書いてありますね。
しかも実際GCされるまで動かないようです。
以下のURLにも同じことが書いてありました。

http://jakarta.apache.org/taglibs/guidelines.html

『アドバンスドJavaServerPages』を読む限りではreleace()は
毎回必ず最後に呼ばれることになっているようですが・・・。
上記のJakartaのガイドラインによると
(Guidelines for tag lifecycle managementの2番)
結局doStartTagの頭で初期化してやるのが一番安全ということなのでしょうか?
それともdoFinally()の中?
私もちょっとわかりません。
結局お役に立てずに申し訳ない限りです。

[ メッセージ編集済み 編集者: ayum 編集日時 2002-12-26 17:47 ]
みやも
ベテラン
会議室デビュー日: 2002/04/22
投稿数: 74
投稿日時: 2002-12-26 19:24
ayumさん、回答ありがとうございます。

>結局doStartTagの頭で初期化してやるのが一番安全ということなのでしょうか?

セッタの後に呼ばれるので、フィールドの値を見て処理を分岐させる場合、
ちょっと都合が悪い場合もありそうです。


>それともdoFinally()の中?

http://java.sun.com/j2ee/sdk_1.3/ja/techdocs/api/javax/servlet/jsp/tagext/TryCatchFinally.html

タグハンドラクラスにimplements TryCatchFinallyして、
メソッドを実装しとけば、確かに呼ばれるようです。
これが使えそうなので、これでいこうと思います。

しかし、はじめて見るメソッドです。。。


>結局お役に立てずに申し訳ない限りです。

とんでもないです。早く的確な回答をいただき、
問題もしぼりこめて、解決策も見い出せました。


初期化のコールバックメソッドがないのが問題なのだろうか?
ayum
常連さん
会議室デビュー日: 2002/03/28
投稿数: 44
お住まい・勤務地: 東京
投稿日時: 2002-12-27 17:22
releace()が呼ばれるタイミングが気になったので、
ちょっと引き続いて調べてみました。
タグリブのreleace()の始めで
System.out.println("----- Begining of releace -----");
と打ち出し、
JVM起動のオプションで-verbose:gcを指定して
ガベージコレクトが起きたタイミングを観察、
gcが起きたタイミングで本当にreleace()が呼ばれるのかを検証してみました。

すると、Tomcat4.1.18-LE-jdk14/JDK1.4.1(Windows)の環境では
gcが起きたタイミングでもFull gcが起きたタイミングでもreleace()は呼ばれず、
なんとTomcatをshutdownするとコンソールが落ちる寸前にまとめて
releace()が実行されていました・・・。
つまり、ガベージコレクトが起きるタイミングではなく、
ガベージコレクトされるタイミングで呼ばれるみたいです。
まぁ、冷静に考えればガベージコレクトが起きるタイミングで
無作為にreleace()がコールされるとタイミングの問題で
おかしな現象が発生する場合もあるでしょうし、
それはないですよね・・・。
でもそれじゃreleace()ってfinalize()と変わらないんじゃ・・・?と思いつつ、
releace()の実行タイミングに納得のいかない私がそこにはいましたとさ。

以上、ご参考まで。

[ メッセージ編集済み 編集者: ayum 編集日時 2002-12-27 17:30 ]
1

スキルアップ/キャリアアップ(JOB@IT)