メタデータの末尾に移動
メタデータの先頭に移動

FAQ

この FAQ のほかに、よく話題になる問題について取り上げた「ハウツー」ガイドが MyFaces wiki ホームページにあります。

MyFaces とは

MyFaces は、Java Community Process の一環として公開されている JavaServer Faces (JSF) 仕様に関連したプロジェクト群です。"Core" プロジェクトは、この仕様の実装です。その他の MyFaces プロジェクトでは、関連する仕様 (Portlet Bridge など) の実装や、(MyFaces Core だけでない) 任意の JSF 実装への機能追加を行っています。

JSF FAQ

ほかに JSF に関する FAQ サイトはありますか?

JSF に関する各種の一般的な問題を取り上げたすばらしい FAQ が www.jsfcentral.com にあります。ほかにも、このような情報を入手できるところはたくさんあります。Web の検索エンジンを活用してください。

JSF SPEC

JSF 仕様の中に気に入らない部分があります。どうすれば変更できますか。

JAVASERVERFACES-SPEC-PUBLIC に課題を作成し、次のバージョンの JSF への提案を送ることができます。提案は JSR のスペックリードが受理し、妥当であると判断されれば、プロジェクトの Issue Tracker に追加されます。

また、MyFaces のユーザー向けと開発者向けのメーリングリストに登録し、これらのメーリングリストに提案を投稿する方法もあります。この場合、必要なら MyFaces PMC のメンバーが、エキスパートグループでの機能の取り込みを後押ししてくれるでしょう。

javax.faces.STATE_SAVING_METHOD の client と server はどう違うのですか?

簡単に言えば、サーバー側での状態保存では、UI コンポーネント (すなわち「ウィジェット」) によって保持される情報は HTTP セッションに格納されるのに対し、クライアント側での状態保存では、ユーザーに送り返されるページ内の hidden フィールドに情報が格納されます。

クライアント側での状態保存では、ユーザーの状態をサーバー上で保持しておくためのメモリが必要ないため、ユーザー数が非常に多いケースでもはるかに柔軟に対応することができます。その一方、各リクエストでネットワークを介して転送されるデータが増えるというデメリットがあります。

クライアント側での状態保存が選択されている場合でも、セッションスコープの Managed Bean は依然として HTTP セッション内に残ります。クライアント側での状態保存が影響するのは、UI コンポーネントが内部的に保持するデータを JSF 実装がどこに置くかだけです。

技術的な詳細については、次のところを参照してください。

ブラウザに表示されるリンクが常に前のページへのリンクなのですが、これはなぜですか?

デフォルトでは、JSF は内部的に「転送 (forward)」操作を使ってページ間を移動します。

たとえば、ユーザーが最初にページ A を表示すると、そのページに相当するコンテンツが送り返されます。このコンテンツは、ページ A を送信先のアドレスとするフォームにラップされています。

ユーザーが、ページの送信につながる何らかの操作 (「保存」ボタンをクリックするなど) を行うと、JSF はこの POST リクエストを受け取り、ページ A のビューを復元して、ポストバック処理を実行します。このとき、ポストバック処理の一環として、ページ A のロジックが JSF フレームワークに対し、今度はページ B を表示する必要があると指示していることがあります。

この場合、デフォルトでは JSF はページ B への内部的な転送を実行し、結局、フォーム送信の結果として、ページ B がレンダリングされてユーザーに返されることになります。

ユーザーの画面に表示されているのは、今度はページ B です。しかしブラウザが知っているのは、何らかのデータをページ A に送信したということだけです。したがって、画面に表示されているコンテンツがたとえページ B であったとしても、ブラウザがナビゲーションバーに表示するのはページ A の URL ということになります。残念ながら、HTTP/HTML では、表示すべき URL はページ B の URL であるということをブラウザに教える手段がありません。したがって、JSF のデフォルトの動作では、ブラウザの URL は、実際に表示されているコンテンツより常に「1 ページ遅れている」ことになります。

これがユーザーにとって奇妙に見えるのはもちろんですが、それだけでなく、これは JSF アプリケーションでページをブックマークすることを困難にしています。ただし、(一般にきわめて対話性の高いステートフルな) JSF アプリケーションで任意のページをブックマークすることは、いずれにしてもあまり意味のあることでないことはたしかです。

こうした「最適化」のもう 1 つのデメリットに、JSF ビュー内の任意の場所での相対リンク (スタイルシートやアイコンへの相対パスなど) の使用は安全ではないということがあります。ブラウザがページ A への送信を実行し、送り返されたものがページ B のコンテンツだった場合、ブラウザは返されたページ内のすべての相対リンクを、既知の最後の URL からの相対リンクとして扱います。したがってページ B の最初のビューでは、すべての相対リンクは A に対する相対リンクになります。もし A が別のディレクトリにあると、ページ B のビュー定義の相対リンクはすべて壊れてしまいます。

1 つの解決策として、<redirect/> でマークしたナビゲーションルールを使用する方法があります。そして、新しいページへの内部転送を実行するのではなく、HTTP のリダイレクトコマンドをブラウザに送信して、ブラウザに新しいページを取得させます。ただ、この方法では効率は落ちます。なぜなら、ブラウザは元のフォーム送信へのレスポンスとしてただちにコンテンツを取得することができず、目的のコンテンツを取得するためにもう 1 度リクエストを行う必要があるからです。この方法には、もう 1 つ重大な問題があります。それは、ページ B の取得が異なるリクエストで行われるため、ページ A がリクエストスコープの変数を介してページ B にデータを渡すことができないという問題です。こうした目的でのリクエストスコープの変数の使用はきわめて便利で、したがってよく使われる方法なのです。

Myfaces FAQ

MyFaces Core を使った方がよいのはなぜですか?

「... すべての Java EE アプリケーションサーバーには JSF の実装がバンドルされています。そのためにしばしば使われるのは、"Mojarra" と呼ばれるリファレンス実装です。しかし、別の JSF 実装をバンドルして、自分のプロジェクトで使うようにすることもできます。この場合、すべての Java EE アプリケーションでサーバーで MyFaces Core を JSF 実装として使用できます。MyFaces Core を使うことの利点の 1 つは、MyFaces Core がログに出力する情報が多く、これがデバッグ時に役立つという点です。デフォルトで MyFaces Core を使っているアプリケーションサーバーを探しているなら、Apache Geronimo がよいでしょう...」 Apache MyFaces 1.2 Web Application Development』の文章を使わせてくれた Bart Kummel に感謝します。

このほかにも、以下の理由から MyFaces Core の使用が推奨されます。

  • "Community over code": MyFaces コミュニティには、JSF について詳しい知識を持っている人が数多く参加しています。ユーザー向けメーリングリストと開発者向けメーリングリストに登録すれば、最新の情報を入手したり、フィードバックを受け取ったり、JSF に関心を持つほかのユーザーと知り合うことができます。この点は考慮すべき重要なポイントです。作業中にバグが見つかることもあれば、JSF について質問する必要が出てくる場合もあるからです。
  • MyFaces では新機能の追加がある: 単に JSF 実装というだけでなく、MyFaces には、JSF の実装それ自体にはない付加機能を提供するさまざまなプロジェクトがあります (Trinidad、Tobago、Tomahawk、ExtVal、CODI、Orchestra、PortletBridge リファレンス実装など)。
  • MyFaces Core は myfaces-builder-plugin を使ってコードを生成: これは Maven プラグインで、myfaces-builder-annotations とともに JSF 開発キットとなっていて、複数の artifact (コンポーネント、コンバータ、バリデータ、クライアントの動作など) の作成と関連ドキュメントの処理を簡単に行うことができ、手作業で処理する必要のあるファイルを減らすのに役立っています。このツールは Java のアノテーションを使って関連するすべての情報を提供し、このツールを使う MyFaces の各 jar には、各バンドルをビルドするのに必要なすべてのメタ情報が含まれた myfaces-metadata.xml があります。このツールは、複合コンポーネントの定義を読み取って、通常のコンポーネント、コンバータ、またはバリデータと統合されたドキュメントを構築することができます。
  • MyFaces は Maven を使っているので、IDE で Maven プロジェクトを開けばコードの編集や再ビルドを簡単に行うことができます。ほとんどの IDE には Maven のサポートが組み込まれています。
  • MyFaces Core は "OSGi" と親和性がある: クラスロードを細かくコントロールする必要がある場合に、特別なセットアップを処理するための SPI インタフェースが用意されています。この点に関しては、たくさんの便利が機能が追加されています。
  • MyFaces Core は、MyFaces UI コンポーネントライブラリおよびアドオン/拡張機能が動作するかどうか毎日テストされています。これらのプロジェクトの多くは、MyFaces と Mojarra のどちらとも (どちらも JSF 標準に基づいて作成されているので) 互換性がありますが、これらのプロジェクトはすべて MyFaces Core で動作するかどうかがテストされるので、MyFaces Core がコードを適切な状態に保つのに役立っています。バグがあった場合も、MyFaces なら (「内輪で」処理できるので) すばやく対処することができます。

MyFaces Core を選択すべきその他の技術的理由については、このブログを参照してください。

問題が起きました。JIRA で課題をオープンすべきですか、それともメーリングリストで質問すべきですか?

質問はすべて MyFaces のユーザー向けメーリングリストに投稿してください。

JIRA で課題を作成するのは、原則として次の場合に限ってください。

  • 同じコードが別の実装 (Sun Mojarra など) では動作するが、MyFaces では動作しない。
  • 同じコードが別のバージョンの MyFaces では動作する。
  • MyFaces のソースコードを調べ、問題を修正するパッチを用意した。
  • メーリングリストで質問したところ、バグであることが確認され、JIRA で課題をオープンするよう求められた。

上記以外のすべてのケースでは、まずユーザー向けメーリングリストに質問を投稿してください。

新しいコンポーネントを寄付するにはどうすればよいですか?

いろいろな方法があります。MyFaces のメーリングリストにメッセージを投稿して、開発者と直接コンタクトを取ったり、どうすべきかを尋ねたりすることもできれば、作成したコンポーネントを Tomahawk issue tracker に載せることもできます。sandbox への参加に関して厳格なルールはありません。必要なものは、優れたコンポーネントであることだけです。

ソースコード jar はどこでダウンロードできますか?

MyFaces Core のリリースバージョンのソースは、以下のところにあります。

MyFaces Core 1.1.x リリース (すなわち JSF 1.1 の実装) には、共有プロジェクト 2.0.x からのコードが含まれていることに注意してください。MyFaces Core 1.2.x リリース (すなわち JSF 1.2 の実装) には、共有プロジェクト 3.0.x からのコードが含まれています。

バージョン 2.0.8 と 2.1.2 以降、共有コードは Core のモジュールとしてバンドルされたので、チェックアウトする必要があるのは、関連タグのフォルダだけです。

Tomahawk のソース

次の場所にも各種ビルドがあります。
http://people.apache.org/builds/myfaces/

IDE で使用できるソース jar は、次の maven2 リポジトリディレクトリから入手できます。

sandbox jar はどこでダウンロードできますか?

まだリリースされていないコードのバイナリは、次の maven ビルドリポジトリから入手できます。

たとえば、sandbox jar は次のところにあります。

「共有」プロジェクトとは何ですか?

もし myfaces-core、tomahawk、tobago、および trinidad が互いに完全に独立したプロジェクトだったら、「共有」コードプロジェクトを用意する必要はありません。各プロジェクトがそれぞれの名前空間内で独自のコードを保守すれば済みます。しかし、これではコードの重複が多く、せっかく割いた労力が無駄になってしまいます。これらのプロジェクトはすべて "MyFaces" という 1 本の傘の下にあるプロジェクトであり、複数のプロジェクトに共通のコードを、「共有」プロジェクトに入れれば、開発と保守の手間を減らすことができ、一連のプロジェクトをより一貫性の高いものにすることができます。

ただ、これらのプロジェクトはそれぞれリリースサイクルが異なっており、さらに tomahawk/tobago/trinidad は MyFaces Core 以外の JSF 実装でも動作しなければなりません。これらの点を考慮して現在採用されているの方法は、共有クラスパッケージの名前を変更するというコンパイルハックです。具体的には、myfaces-impl jar ファイルに収めるときは、コードの名前を "org.apache.myfaces.shared_impl" に変更し、tomahawk jar ファイルに収めるときは、コードの名前を "org.apache.myfaces.shared_tomahawk" に変更するといったことを行っています。この方法の場合、各プロジェクトは、そのプロジェクトで必要となるすべての共有サポートクラスとともに (適切な機能とバグ修正も含めて) デプロイでき、別に共有 jar ファイルを用意したり、同じクラスの定義が衝突するのを心配したりする必要はありません。これらのプロジェクトのいずれかをアップグレードしても、同じ環境にデプロイされたほかのプロジェクトには影響がありません。

これらの共有コードのリリース番号は、共有コードを使っているプロジェクトのリリース番号とは別になっています。たとえば、
http://svn.apache.org/repos/asf/myfaces/tomahawk/tags/1_1_3/core/pom.xml
では、tomahawk 1.1.3 が共有プロジェクトのバージョン 2.0.2 に依存すると記述されています。

なお、ファイル myfaces-impl-1.1.4.jar には共有プロジェクトの .class ファイルが含まれていますが、myfaces-impl-1.1.4-sources.jar には、対応するソースファイルは含まれておらず、Java ソースにアクセスするには myfaces-shared-impl-2.0.3.jar を追加する必要があることに注意してください。共有ライブラリを使っている MyFaces プロジェクトの最近のリリースでは、対応する -sources jar に共有プロジェクトのソースが含まれるようになっているので、現在は別のソース jar を追加する必要はありません。

バージョン 2.0.8 と 2.1.2 以降、共有コードは Core のモジュールとしてバンドルされ、MyFaces Core はより使いやすくなっています。

MyFaces からきれいに整形された HTML 出力を得るにはどうすればよいですか?

[[http://jtidy.sourceforge.net]] プロジェクトでは、送信前にレスポンスメッセージを再整形する [[http://jtidy.sourceforge.net/multiproject/jtidyservlet/filter.html]] を提供しています。

Web ブラウザの Mozilla Firefox には、サーバー側ではいっさいの変更を必要とせずに、ソースを適切に整形して表示する拡張機能 "[[https://addons.mozilla.org/extensions/moreinfo.php?id=697]]" がオプションで用意されています。

MyFaces の一部のバージョンでは、web.xml で指定できるコンテキストパラメータ "org.apache.myfaces.PRETTY_HTML" を使って、出力の整形を有効にすることができます。ただし、適切に動作するためにはすべてのレンダラーのサポートが必要になるため、このオプションはきちんとサポートされたためしがありません。この機能は、MyFaces の将来のバージョンから削除される可能性があります。

MyFaces Core と Tomahawk のリリースのバージョン番号にはどのような意味があるのですか?

MyFaces Core は、1.1.1 のように 3 つの部分からなるバージョン番号を使っています。ただし、値の意味は通常のバージョン番号の付け方とは異なっています。最初の 2 つの数字は、そのリリースがどの JSF 仕様の実装であるかを示しています。最初の 2 つの数字が同じ 2 つのリリースについては、JSF 仕様のバイナリ API には変更はないので、バイナリ互換であることが保証されます。つまり、JSF で指定された機能を使用している既存のコードは、従来同様 (従来の動作にバグがあった場合は別ですが) 動作し続けます。

Tomahawk ライブラリも、同様のバージョン番号の付け方を採用しています。ただし、JSF 1.2 仕様は JSF 1.1 仕様と後方互換性があるので、バージョン 1.1.x の Tomahawk リリースは、JSF 1.2 でも問題なく動作します。しかしながら、Tomahawk リリースは以前の Tomahawk リリースとバイナリ互換であることは保証されない点に注意してください。3 番目の数字の増加は、単純にリリースカウントの増加であり、「パッチバージョン」を意味しているのではありません。Tomahawk のリリースには、単なる「バグフィクス」リリースはありません。

また、Tomahawk リリースは、リリースの時点において利用可能な MyFaces と JSF 実装の最新のバージョンでのみテストされていることに注意してください。これらのライブラリのほかのバージョン、またはほかのライブラリでも、問題なく動作すると期待されますが、保証はされていません。とくに、初期のリリースの Tomahawk を MyFaces Core で実行する場合、一般には使用するバージョンは正確に一致している必要がありました (これは「共有」ライブラリの使われ方が原因です)。この点は現在では改善されており、最近の Tomahawk リリースは、ほぼ問題なく、さまざまなバージョンの MyFaces Core で動作するはずです。

javax.faces.model.DataModel はなぜ serializable ではないのですか?

(UIData コンポーネントで使われる) DataModel クラスは、Render Response フェーズと Restore View フェーズとの間で保存する必要のある状態を持っていません。したがって、このクラスが serializable である必要はありません。

serializable にしたい Managed Bean があって、DataModel 型のメンバがある場合には、そのメンバを transient とマークしてください。

Managed Bean とともに DataModel 内のリストを直列化したい場合には、次のようにしてください。

SomeManagedBean.java
public class SomeManagedBean implements Serializable {
  private List myData;

  private transient DataModel myDataModel;

  public DataModel getDataModel() {
    if (myDataModel == null) {
      myDataModel = new ListDataModel(myData);
    }
    return myDataModel;
  }
}

日付に間違った日時が表示されるのですが?

JSF 仕様では、日付から文字列へのコンバータに対し、デフォルトでは標準 UTC (別名 GMT) タイムゾーンの使用を義務付けています。

リリース 1.1.0 およびそれ以前の MyFaces は JSF の仕様に従っておらず、デフォルトでは
サーバーのタイムゾーンを使用していました。

変換時に使用するタイムゾーンをコントロールするには、次のように明示的なコンバータをアタッチします。

    <f:convertDateTime timeZone="Antarctica/South_Pole"  .../>

または

    <f:convertDateTime timeZone="#{bean.timeZone}"  .../>

ここで、#{bean.timeZone} は文字列 ID、または TimeZone インスタンスを返します。

MyFaces Commons コンバータプロジェクトで提供されている独自のコンバータタグは f:convertDateTime に似ていますが、デフォルトではサーバーのタイムゾーンを使用します。

    <mcc:convertDateTime/>

別のやり方として、標準のコンバータをオーバーライドする独自のコンバータを登録すれば、日付から文字列へのすべての変換に対し、指定した独自のコードが適用されるようになります。

Managed Bean に別の Managed Bean からアクセスするには

Managed Bean に別の Managed Bean からアクセスする方法」を参照してください。

JSP ページでの前方参照の扱い

注: ここでの説明が該当するのは、JSF 1.1 と JSP を使っているプロジェクトだけです。JSF 1.2 または Facelets を使っているプロジェクトでは、この項目は無視してかまいません。

場合によっては、JSP ページ内のあるコンポーネントから別のコンポーネントを ID で参照する必要があることがあります。よくあるケースは、tomahawk の t:dataScroller コンポーネントを使う場合です。この場合、参照する側のコンポーネントが、参照先のコンポーネントよりもページ内で後に出現すれば問題は生じません。しかし、コンポーネントの順序が逆の場合には、エラーが発生します。


  <t:dataScroller for="someTable" .../>

  <t:dataTable id="someTable" .../>

JSP を使っている場合、コンポーネントの作成とレンダリングは、その JSP ページ内でシングルパスで行われます。これは、dataScroller がレンダリングされるときに、dataScroller が参照している dataTable はまだ作成されておらず、結果として "cannot find UIData" というエラーメッセージが表示されることを意味します。この問題は、"for" 属性または同様のメカニズムを使って何らかの関連コンポーネントを参照するほかのコンポーネントでも生じます。

この問題は、対象となるコンポーネントを、「子をレンダリングする」親コンポーネントにラップすれば解決できます。このようなコンポーネントは、入れ子になったコンポーネントを 2 パス (作成、ついでレンダリング) で処理します。

  <h:panelGroup>
    <t:dataScroller for="someTable" .../>
    <t:dataTable id="someTable" .../>
  </h:panelGroup>

この方法には、いくつか軽微な欠点があります。JSF 1.1 では、子をレンダリングするコンポーネントは、入れ子になった「テンプレートテキスト」および非 JSF の JSP タグと適切に対話することができません。このようなコンポーネント内では、非 JSF のJSP タグの使用を避け、「テンプレートテキスト」を f:verbatim タグでラップすることで、問題を回避できます。

別の方法として、独立した「作成」パスと「レンダリング」パスを使うプレゼンテーション技術に移行するやり方もあります。Facelets と Clay はどちらもこうした技術を採用しています。

Managed Bean のプロパティがすべて設定された時点を把握するにはどうすればよいですか?

Managed Bean はデフォルトコンストラクタ (すなわち引数なしのコンストラクタ) を持たなければなりません。Managed Bean にプロパティ宣言があれば、対応する適切なセッターメソッドが呼び出されます。ただし、Managed Bean のプロパティの ''すべて'' の定義が済んだ時点で、何らかの初期化処理を行いたいこともよくあります。

Spring では、初期化後 (post-initialisation) に実行されるコールバックが用意されていて、InitializingBean を実装しているすべての Bean で afterPropertiesSet メソッドが呼び出されるようになっています。JSF にはこれに正確に対応するものはありませんが、次のような方法を通じて似たようなしくみを用意することができます。

  • Bean で "public void setInitialized(boolean state)" といったセッターメソッドを定義する。
  • 対応するプロパティをその Bean の最後に管理されるプロパティとして定義する。
  <managed-bean>
    ....
    <managed-property>
      <property-name>initialized</property-name>
      <value>true</value>
    </managed-property>
  </managed-bean>

JSF 仕様では、管理されるプロパティは宣言された順序で初期化する必要があると定められています。したがって、setInitialized メソッドはほかのすべてのプロパティの設定が終わった後に初めて呼び出されます。

JSF の将来のバージョンでは、Managed Bean のメソッドに @PostConstruct と @PreDestroy というアノテーションを付けることができるようになる可能性があります。詳細については、次のところを参照してください:

「作成した PhaseListener が 2 度呼び出されてしまいます」

JSF 仕様はすべての JSF 実装に対し、起動時に /WEB-INF/faces-config.xml を自動的にロードするよう求めています。したがって、次のコンテキストパラメータは不要です。

<context-param>
   <param-name>javax.faces.CONFIG_FILES</param-name>
   <param-value>/WEB-INF/faces-config.xml</param-value>
</context-param>

このコンテキストパラメータをデプロイメント記述子に記述すると、どの JSF 実装でも構成を 2 度ロードすることになり、したがって各フェーズリスナーが 2 回登録されることになります。

Portlets を使っている場合は、[[http://issues.apache.org/jira/browse/MYFACES-1338]] を参照してください。

「dataTable 上のコマンドのアクションリスナーとアクションがトリガされません」

アクションリスナーとアクションは、アクションソース ( h:commandLink, h:commandButton ) がレンダリングされていないときは呼び出されません。アクションソースが dataTable 上にあり、dataTable の value 属性が、リクエストスコープのデータソースを指し示している場合、アクションソースは以後のリクエストではレンダリングされません。

<h:dataTable value="#{requestScopedBean.dataModel.wrappedData}" />
	<h:column>
		<h:commandLink value="click here" action="#{backingBean.willNotFire}" />
	</h:column>
</h:dataTable>

アクションソース ( h:commandLink, h:commandButton ) がレンダリングされないのは、以後のリクエストではデータソースが存在しないためです (データソースは、最初のリクエストの完了後に、ガベージコレクトされています)。

この問題を解決するには、t:saveState を使うか、またはリクエストスコープの Backing Bean をセッションスコープに入れます。

<t:saveState value="#{myRequestScopedBean.dataModel.wrappedData}" />

t:saveState を使う方が、セッションスコープよりも望ましい解決策です。

Calendar、Tree などが動作しないか、JavaScript エラーになります

MyFacesExtensionsFilter を構成する必要があります。[http://myfaces.apache.org/tomahawk/extensionsFilter.html] を参照してください。

Error "ExtensionsFilter not correctly configured."

"java.lang.IllegalStateException: ExtensionsFilter not correctly configured. JSF mapping missing. JSF pages not covered" というエラーが発生し、すべての構成が適切に行われている場合は、次のことをチェックしてください。

1. [http://myfaces.apache.org/tomahawk/extensionsFilter.html] で説明されているように、正しいフィルターが構成されていることを確認します。
2. Servlets 2.4 を使っている場合、ExtensionsFilter は実行されないので、jsp:forward または request.getDispatcher().forward でページに転送することはできません。代わりに、response.sendRedirect() を使うようにしてください。

Websphere 上で Tomahawk ExtensionsFilter が動作しません

その場合、おそらく特別な websphere プロパティ com.ibm.ws.webcontainer.invokefilterscompatibility に true を設定する必要があります。

Websphere は、リクエスト URL がサーブレットにマップされない場合、かつディスク上のファイルにもマップされない場合には、フィルタを実行しないようです。
Tomahawk ExtensionFilter URL は、このいずれも行わないので、単に Websphere がフィルタを実行しないだけです。上に示したプロパティに true を設定すると、Websphere の動作も
地球上に存在するほかのすべてのサーブレットエンジンと同じにあるので、あらゆる場合にフィルタが実行されるようになります。

Tomahawk :popup タグを使うと、HtmlPopupRenderer.encodeEnd で java.lang.NullPointerException が発生します

facet 名は "popup" としてハードコードする必要があります。

Tomahawk dataScroller を使うと、com.sun.facelets.tag.jsf.ActionSourceRule で ClassCastException が発生します

http://myfaces.apache.org/download.html にアクセスし、最新の Tomahawk jar にアップデートしてください。

Tomahawk を使うと、次のエラーが発生します: java.lang.NoClassDefFoundError: org/apache/commons/lang/builder/HashCodeBuilder

http://myfaces.apache.org/download.html から最新の Jakarta Commons jar をダウンロードしてください (MyFaces Core 1.1.3 またはそれ移行の配布パッケージの中にあります)。

WARNING: The AdfFacesFilter has not been installed. ADF Faces requires this filter for proper execution.

web.xml で、Faces Servlet javax.faces.webapp.FacesServlet 1 のように、FacesServlet の名前に "Faces Servlet" を指定している部分で、servlet-name を adfFaces Faces Servlet にしてください。

ADF コンポーネントでポップアップもサブミットも動作しません (JavaScript がまったく動作しません)。Error: submitForm is not defined

ADF リソース (.js ファイル、画像など) の提供方法を web.xml の resources oracle.adf.view.faces.webapp.ResourceServlet および resouces /adf/* で定義する必要があります。

MyFaces コンポーネントでポップアップもサブミットも動作しません (JavaScript がまったく動作しません)。

MyFaces リソース (.js ファイル、画像など) の提供方法を web.xml で MyFacesExtensionsFilter エントリを使って定義する必要があります。

Render Response フェーズの開始時に ADF Faces で NullPointerException が発生する、またはレンダリングに関する警告が表示される

Mar 21, 2006 12:10:15 AM org.apache.myfaces.renderkit.html.HtmlRenderKitImpl getRenderer WARNING: Unsupported component-family/renderer-type: oracle.adf.Panel/oracle.adf.Group
Mar 21, 2006 12:10:15 AM oracle.adf.view.faces.component.UIXComponentBase _getRendererImpl WARNING: Could not find renderer for CorePanelGroup[UIXFacesBeanImpl, id=_id38], rendererType = oracle.adf.Group
Mar 21, 2006 12:10:15 AM org.apache.myfaces.renderkit.html.HtmlRenderKitImpl getRenderer WARNING: Unsupported component-family/renderer-type: oracle.adf.Command/oracle.adf.Link
Mar 21, 2006 12:10:15 AM oracle.adf.view.faces.component.UIXComponentBase _getRendererImpl WARNING: Could not find renderer for CoreCommandLink[CommandLinkFacesBean, id=_id41], rendererType = oracle.adf.Link
Mar 21, 2006 12:10:15 AM org.apache.myfaces.renderkit.html.HtmlRenderKitImpl getRenderer WARNING: Unsupported component-family/renderer-type: oracle.adf.Output/oracle.adf.Formatted
SEVERE: Error Rendering View[/main.xhtml] java.lang.NullPointerException at 
oracle.adfinternal.view.faces<WBR>.uinode.FacesRenderingContext<WBR>.setRenderingProperty(FacesRenderingContext.java:157) at 
oracle.adfinternal.view.faces<WBR>.ui.RenderedNodeRenderingContex<WBR>t.setProperty(RenderedNodeRenderingContext<WBR>.java:162) at 
oracle.adfinternal.view.faces<WBR>.ui.RootRenderingContext.init(RootRenderingContext.java:81) at oracle.adfinternal.view.faces<WBR>.uinode.FacesRenderingContext.
(FacesRenderingContext.java:106) at oracle.adfinternal.view.faces<WBR>.uinode.FacesRenderingContext<WBR>.createRenderingContext(FacesRenderingContext.java:79) 
at oracle.adfinternal.view.faces<WBR>.uinode.UINodeRendererBase<WBR>.getRenderingContext(UINodeRendererBase.java:89) at 
oracle.adfinternal.view.faces<WBR>.uinode.FacesRenderingContext<WBR>.getRenderingContext(FacesRenderingContext.java:66) at 
oracle.adfinternal.view.faces<WBR>.uinode.FacesRenderingContext<WBR>.getRenderingContext(FacesRenderingContext.java:52) at 
oracle.adfinternal.view.faces<WBR>.renderkit.htmlBasic.UINodeRend<WBR>erer.getRenderingContext(UINodeRenderer.java:79) at 
oracle.adfinternal.view.faces<WBR>.renderkit.htmlBasic.UINodeRend<WBR>erer.encodeBegin(UINodeRenderer.java:38) at 
javax.faces.component.UICompone<WBR>ntBase.encodeBegin(UIComponentBase.java:512) at 
com.sun.facelets.FaceletViewHan<WBR>dler.encodeRecursive(FaceletViewHandler.java:555) at 
com.sun.facelets.FaceletViewHan<WBR>dler.encodeRecursive(FaceletViewHandler.java:562) at 
com.sun.facelets.FaceletViewHan<WBR>dler.encodeRecursive(FaceletViewHandler.java:562) at 
com.sun.facelets.FaceletViewHan<WBR>dler.renderView(FaceletViewHandler.java:457) at 
org.apache.myfaces.lifecycle<WBR>.LifecycleImpl.render(LifecycleImpl.java:367) at 
javax.faces.webapp.FacesServlet<WBR>.service(FacesServlet.java:138) at 
org.apache.catalina.core<WBR>.ApplicationFilterChain<WBR>.internalDoFilter(ApplicationFilterChain.java:252) at 
org.apache.catalina.core<WBR>.ApplicationFilterChain<WBR>.doFilter(ApplicationFilterChain.java:173) at 
org.apache.myfaces.webapp<WBR>.filter.ExtensionsFilter<WBR>.doFilter(ExtensionsFilter.java:130) at 
org.apache.catalina.core<WBR>.ApplicationFilterChain<WBR>.internalDoFilter(ApplicationFilterChain.java:202) at 
org.apache.catalina.core<WBR>.ApplicationFilterChain<WBR>.doFilter(ApplicationFilterChain.java:173) at 
org.apache.catalina.core<WBR>.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at 
org.apache.catalina.core<WBR>.StandardContextValve.invoke(StandardContextValve.java:178) at 
org.apache.catalina.authenticat<WBR>or.AuthenticatorBase.invoke(AuthenticatorBase.java:432) at 
org.apache.catalina.core<WBR>.StandardHostValve.invoke(StandardHostValve.java:126) at 
org.apache.catalina.valves<WBR>.ErrorReportValve.invoke(ErrorReportValve.java:105) at 
org.apache.catalina.core<WBR>.StandardEngineValve.invoke(StandardEngineValve.java:107) at 
org.apache.catalina.connector<WBR>.CoyoteAdapter.service(CoyoteAdapter.java:148) at 
org.apache.coyote.http11<WBR>.Http11Processor.process(Http11Processor.java:869) at 
org.apache.coyote.http11<WBR>.Http11BaseProtocol$Http11Conne<WBR>ctionHandler.processConnection(Http11BaseProtocol.java:667) at 
org.apache.tomcat.util.net<WBR>.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527) at 
org.apache.tomcat.util.net<WBR>.LeaderFollowerWorkerThread<WBR>.runIt(LeaderFollowerWorkerThread.java:80) at 
org.apache.tomcat.util.threads<WBR>.ThreadPool$ControlRunnable.run(ThreadPool.java:684) at 
java.lang.Thread.run(Thread.java:595)

FaceletViewHandler がコメントアウトされていること、faces-config.xml で ADF Faces のデフォルトの renderkit が oracle.adf.core として定義されていること (ADF Faces 実装では、非 ADF コンポーネントも通常の方法でレンダリングされるようになっており、ほかの JSF コンポーネントとも安全に共存できることに注意してください)、および web.xml に ADF Faces 用の行 oracle.adf.view.faces.ALTERNATE_VIEW_HANDLER com.sun.facelets.FaceletViewHandler AdfFacesFilter oracle.adf.view.faces.webapp.AdfFacesFilter AdfFacesFilter FacesServlet が含まれていることを確認してください。

最初に貢献してくれた Murray Brandon に感謝します。

MyFaces 1.1.5 になって selectItem が動作しなくなりました

MyFaces 1.1.4 およびそれ以前のバージョンでは、select コンポーネントが正しく実装されていませんでした。動作に問題はありませんでしたが、select コンポーネントでは UISelectItems からの値を変換しないことになっていました。たとえば、1.1.4 なら次のコードは動作していました。

<f:selectOneMenu value="#{bean.intValue}"><f:selectItem itemValue="1" /></selectOneMenu>

この記述で動作していた理由は、過去のコードが selectOneMenu のコンバータを使って selectItem からの値を変換していたためです。JSF の仕様によれば、これは行わないことになっています。したがって、selectOneMenu からの変換された値と、selectItem のいずれかの itemValue とが同一である (equals 関数テストをパスする) ことが重要です。したがって上の例では、itemValue は、数字をその中に含む文字列ではなく、整数値でなければなりません。

以前の動作のままにしたい場合は、入力コントロールからコンバータを使って値を変換する独自の selectItem コンポーネントを作成するとよいでしょう。次にコードを示します。

UISelectItem.java
public class UISelectItem
  extends javax.faces.component.UISelectItem
{
  public final static String COMPONENT_TYPE = "org.apache.myfaces.wiki.SelectItem";
  private Boolean convertValue;

  /**
   * @return the convertValue
   */
  public boolean getConvertValue()
  {
    if (this.convertValue != null) return this.convertValue;
    ValueBinding vb = getValueBinding("convertValue");
    return (vb == null) ?true : (Boolean) vb.getValue(getFacesContext());
  }

  /**
   * @param convertValue the convertValue to set
   */
  public void setConvertValue(boolean convertValue)
  {
    this.convertValue = convertValue;
  }

  /**
   * @see javax.faces.component.UISelectItem#getItemValue()
   */
  @Override
  public Object getItemValue()
  {
    Object value = super.getItemValue();
    
    if (getConvertValue())
    {
      UIInput parent = null;
      for (UIComponent comp = getParent(); comp != null; comp = comp.getParent())
      {
        if (comp instanceof UIInput)
        {
          parent = (UIInput)comp;
          break;
        }
      }
      if (parent != null)
        value = getConvertedValue(getFacesContext(), parent, value);
    }
    return value;
  }

  /**
   * @see javax.faces.component.UISelectItem#saveState(javax.faces.context.FacesContext)
   */
  @Override
  public Object saveState(FacesContext context)
  {
    return new Object[] {
      super.saveState(context), convertValue, };
  }

  /**
   * @see javax.faces.component.UISelectItem#restoreState(javax.faces.context.FacesContext, java.lang.Object)
   */
  @Override
  public void restoreState(FacesContext context, Object state)
  {
    Object[] arr = (Object[]) state;
    int index = -1;
    super.restoreState(context, arr[++index]);
    this.convertValue = (Boolean) arr[++index];
  }

  private Object getConvertedValue(FacesContext context, UIInput input, Object value)
    throws ConverterException
  {
    Renderer renderer = getRenderer(context);
    if (renderer != null)
      return renderer.getConvertedValue(context, this, value);
    else if (value instanceof String)
    {
      Converter converter = RendererUtils.findUIOutputConverter(
        context, input);
      if (converter != null)
        return converter.getAsObject(context, this, (String)value);
    }
    return value;
  }
}

この新しいコンポーネントを通常の JSF の方法で登録します。

ラベル

faq faq Delete
question question Delete
myfaces myfaces Delete
jsf jsf Delete
usage usage Delete
Enter labels to add to this page:
Please wait 
Looking for a label?Just start typing.