過去のエントリ「PrimeFacesでManaged Bean内の判定結果に応じてダイアログの表示有無を制御をする方法」でPrimeFacesのダイアログ表示有無制御を動的にする方法をまとめました。
当時これを検証していた環境では正常に動作していたのですが、現在の開発環境に埋め込んだ所、なんと動かなくなりました(-_-;
すごくすごくハマったので、まとめておきます(多分レアケースですが、同じこと挑戦する人がいるかもしれないので…)。
現在の開発では、PrimeFacesの画面部品を利用していますが、それを複合コンポーネント(Composite Component)に包み、その中にCSSも埋め込むことで、皆が同じようなレイアウトで簡単に配置できるようにしています。
で、これらは1つのjarファイルとして固めて、ライブラリのようにしています。
このライブラリのpom.xmlは普通に
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>3.5</version>
</dependency>
と書いてPrimeFacesを参照していました。
他のプロジェクトがライブラリを参照すると
上記ライブラリを他のプロジェクトで組み込むと、以下画像のようになります。
XXXUiComponentというのが自前で固めたjarです。
なお、ライブラリを利用する側のプロジェクトではPrimeFacesの依存性を記述していないのですが、上記jarが参照しているためか、自動的に「primefaces-3.5.jar」が表示されています。
で、実はこれが問題なのですが…。試しにXXXUiComponentのjarを開いてみると
PrimeFacesのcomponent群がいます。
あれ、これって「primefaces-3.5.jar」と二重定義になっちゃわないの??みたいな。
今まで特に問題なく挙動していたので、気にしなかったのですが(これが問題だった)、冒頭に書いたようにダイアログ制御が動かなくなる現象が起きました。
最初はなぜダイアログが出ないのか、まったくわからず、かなりハマりました。
唯一みつかったのが以下の情報
http://forum.primefaces.org/viewtopic.php?f=3&t=24368
JSFでは全くエラーがでなくて、なんでなんで、って思ってChromeやFireBugでJavaScriptを追いかけた所
SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data
と出ていたのです。で、上記の掲示板みると、いまいち明確な対応情報がないのですが、「2回」とか「extension」とか、そんなキーワードが。
このextensionというのはPrimeFacesの応答に含まれるデータらしく、試しにFiddlerでHTTPのパケットみてみたところ
掲示板の通り2重に呼ばれてる!!
で、試しに、ライブラリのほうでpom.xmlを
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>3.5</version>
<scope>provided</scope>
</dependency>
とprovidedにして、ライブラリを利用しているプロジェクト側で明示的に
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>3.5</version>
</dependency>
と定義しました。こうするとライブラリ内にはPrimeFacesのcomponentが含まれない状態となり、とりあえず二重定義にはならないようです。
で、パケットみると
extensionが1回になって、ダイアログもちゃんとでた!!!
もう諦める寸前くらいまでいったどハマりでした。JSFなのかPrimeFacesなのかわかりませんが、エラーがわかりにくいのは辛いですね。
まとめ
PrimeFacesを単体で普通に利用していれば何も問題ありません。
ただ、プロジェクトでの再利用とかを考えて、PrimeFacesをラップするようなことをして参照するような形とした場合は上記のようなケースがあるかもしれないので、注意が必要かもしれません。