読者です 読者をやめる 読者になる 読者になる

Challenge Java EE !

Java EEを中心に趣味や仕事における開発メモを書いています。

PrimeFacesをラップしてハマったこと

Jar 複合コンポーネント PrimeFaces ConfirmDialog

過去のエントリ「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を参照していました。

他のプロジェクトがライブラリを参照すると

上記ライブラリを他のプロジェクトで組み込むと、以下画像のようになります。

f:id:kikutaro777:20130301211338j:plain

XXXUiComponentというのが自前で固めたjarです。
なお、ライブラリを利用する側のプロジェクトではPrimeFacesの依存性を記述していないのですが、上記jarが参照しているためか、自動的に「primefaces-3.5.jar」が表示されています。

で、実はこれが問題なのですが…。試しにXXXUiComponentのjarを開いてみると
PrimeFacesのcomponent群がいます。

f:id:kikutaro777:20130301211550j:plain
f:id:kikutaro777:20130301211558j:plain

あれ、これって「primefaces-3.5.jar」と二重定義になっちゃわないの??みたいな。

今まで特に問題なく挙動していたので、気にしなかったのですが(これが問題だった)、冒頭に書いたようにダイアログ制御が動かなくなる現象が起きました。

最初はなぜダイアログが出ないのか、まったくわからず、かなりハマりました。
唯一みつかったのが以下の情報

http://forum.primefaces.org/viewtopic.php?f=3&t=24368

JSFでは全くエラーがでなくて、なんでなんで、って思ってChromeFireBugJavaScriptを追いかけた所

SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data

と出ていたのです。で、上記の掲示板みると、いまいち明確な対応情報がないのですが、「2回」とか「extension」とか、そんなキーワードが。

このextensionというのはPrimeFacesの応答に含まれるデータらしく、試しにFiddlerでHTTPのパケットみてみたところ

f:id:kikutaro777:20130301211730j:plain

掲示板の通り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が含まれない状態となり、とりあえず二重定義にはならないようです。

で、パケットみると

f:id:kikutaro777:20130301211740j:plain

extensionが1回になって、ダイアログもちゃんとでた!!!

もう諦める寸前くらいまでいったどハマりでした。JSFなのかPrimeFacesなのかわかりませんが、エラーがわかりにくいのは辛いですね。

まとめ

PrimeFacesを単体で普通に利用していれば何も問題ありません。

ただ、プロジェクトでの再利用とかを考えて、PrimeFacesをラップするようなことをして参照するような形とした場合は上記のようなケースがあるかもしれないので、注意が必要かもしれません。

にほんブログ村 IT技術ブログへ
にほんブログ村
にほんブログ村 IT技術ブログ Javaへ
にほんブログ村