JSPフラグメントバンドルへの依存性を追加する技術者向けテクニカルtips2018.12.27JSPフラグメントバンドルへの依存性を追加するJSPフラグメントバンドルへの依存性を追加する方法をご紹介。XMLのオーバーライドジェダイ(Millen)に戻るプロジェクト例まとめはじめにこんにちは。日本ライフレイ、デベロッパーアドボケイトの竹生(たけお)です。今回は、JSPフラグメントバンドルへの依存性を追加する方法を紹介します。以下の知識レベルの方たち、ユースケースが対象です。DXP開発に必須の知識*レベルの定義については、こちらのブログの冒頭で紹介しています。Bundles“”を翻訳したものです。配信元または著者の許可を得て配信しています。Architect/リードコンサルタント。Communityサイトにて、多くの技術情報を投稿するなど精力的に活動しています。先日、JSPフラグメントバンドルへ新しい依存関係を導入できないことに悩んでいました。これができないと、JSPオーバーライドは、すでにサポートされている要素をページ上で再構成、または追加/削除する事以外あまり役に立ちません。これは、JSPオーバーライドで出来ることのほんの一部です。元のポートレット開発者が検討していなかったような、新機能を追加するケースはよくあります。新しいサービスを追加して、JSP内からそのサービスを利用してエンティティを取得できるようにする、というケースです。JSPフラグメントバンドルと同等のことをするのに、JSPオーバーライドを初めて試した際、私は失望しました。"Installed"となりますが、未解決の参照があったために、resolvedステータスまで到達できなかったのです。Dyankovが以下のような提案をしてくれました:仕様によると:...フラグメントバンドルの要件と機能は、フラグメントがホストに接続されている場合、ホストの要件、および機能の一部として処理されます。宣言型サービスをフラグメントに提供する場合も、仕様は明確です。フラグメントに指定されたサービス・コンポーネント・マニフェスト・ヘッダーは、SCRによって無視されます。バンドルのService-Componentマニフェストヘッダーによって参照されるXMLドキュメントは、添付されたフラグメントに含まれる可能性があります。*.xmlがある場合、フラグメントは新しいXMLファイルをOSGI-INFフォルダに置くことができ、SCRによって処理されます。Milenは時々、私がただの開発者ということを忘れて、OSGiの達人であれば理解できるであろうアドバイスをしてくれます。いうわけで、私にはまだ、JSPフラグメントバンドルへの疑問が残りました。本ブログのでは、その疑問を調べた結果をご紹介したます。これは、OSGiコンテナ内のDSコンポーネントのサービスレジストリとライフサイクル管理、バンドルの開始/停止時のサービスの開始/停止、DSコンポーネントの@Reference依存関係の結びつけを担当します。Felixの実装に依存しているため、実際にはLiferayコンポーネントではなく、Liferayが意味するところのオーバーライドには役に立ちません。JSPフラグメントバンドルのサービスにアクセスするために行うべきことは、サポートされているOSGiメカニズムを経由する以外ありません。したがって、上記のMilenのアドバイスの鍵は、「バンドルのサービスコンポーネントマニフェストヘッダーによって参照されるXMLドキュメントが、添付されたフラグメントに含まれる可能性があります。バンドルホストのコンポーネントの1つに、オーバーライドXMLファイルを提供し、新しい依存関係を注入できるかもしれないということです。サービス・コンポーネント・マニフェストXMLBNDのツールは、みなさんがご存知のように、バンドルのjarを作成するのにとても役立ちます。これらのタスクの1つは、サービス・コンポーネント・マニフェストおよびすべてのXMLファイルを生成することです。これらのファイルのすべての内容は、基本的にSCRが依存関係解決、コンポーネントを結びつけるのに必要なメタデータです。@ComponentでJavaクラスに注釈を付けると、そのコンポーネントがDSサービスであることが示されます。Manifestにエントリを追加します(したがって、SCRはバンドル開始時にコンポーネントを処理します)。サービス・コンポーネント・マニフェストは、バンドルのMANIFEST.MFファイル内のサービス・コンポーネント・キーであり、各コンポーネントごとに1つずつ、OSGI-INF内の個々のXMLファイルをリストします。これらのXMLファイルは、コンポーネントを実装するJavaクラス、コンポーネントが提供するサービス、コンポーネントのすべての参照詳細およびプロパティを指定して、SCRのコンポーネントを定義します。したがって、バンドル・ジャーを持っていれば、それを展開し、MANIFEST.MFファイルを調べ、Service-Componentキーを探します。com.example.package.JavaClass.xmlファイル(パッケージとクラス)があります。マニフェストとXMLドキュメントについて知ったので、定期的に予定されているプログラムに戻ることができます。Componentマニフェストヘッダーによって参照されるXMLドキュメントが、添付されたフラグメントに含まれる可能性があるため、これらのファイルの1つを上書きできる必要があります。これは、新しいファイルを追加できないことを示唆していますが、既存のファイルを上書きすることはできます。したら、新しい依存関係を導入するためのオーバーライドXMLファイルを作成できるのか?(クラスを変更できないため、実際にはオリジナルに直接バインドすることはできません)、少なくともバンドルには新しい依存関係は作成できるのか?実際にこの新しい知識すべてを使い、テストを試してみましたが、うまくいきませんでした。XML上書きは機能していません。""XMLファイルがクラスローダによってロードされ、SCRがオーバーライドを無視するようにホストバンドルがフラグメントバンドルの前に来るため、オーバーライドは機能しません。XMLをオーバーライドすることはできません。フラグメントバンドルにのみ新しいものを追加できます。"“あなたは新しいXMLファイルを追加できないと言いましたが、ホストバンドルのMANIFEST.MFファイルのService-Componentにリストされているものだけが、ロード中にSCRによって使用されています。*のようなワイルドカードを使用するようにService-Componentキーを変更し、SCRはフラグメントバンドルだけでなくホストバンドルからもロードします。これはあまり推奨できるやり方ではないですが、うまくいくでしょう。”“それはできません。Milen、私はLiferayホストバンドル上でJSPフラグメントバンドルを実行しています。したがってサービスコンポーネントのマニフェスト値を変更することはできません。それができているのであれば、こうしたフラグメントのバンドルをする必要はそもそもなく、変更をホストバンドルに直接適用するだけで実現できてるはずです。新しいプランを立てて、検証するためのサンプルプロジェクトに取り掛かりました。今回の例では、JSPフラグメントバンドルのオーバーライドが含まれていなければなりません。ここで必要以上にコーディングする必要はありません。ポータルのJSPやサービスから選んでみましょう。要件:ログインフォームに、現在のメンバーシップリクエスト数を表示します。自動的に処理されるサイトアクセスのためのメンバーシップリクエストと、何人がサイトアクセスを待っているのかを数えて表示することで、サイトの人気度を示すことができる例です。これを実現するには、login-webホスト・バンドルのlogin.jspページ内のMemberRequestLocalServiceにアクセスする必要があります。このサービスはcom.liferay.invitation.invite.members.apiバンドルに定義されており、現在ログインWebモジュールとは何ら接続されていません。今回、コマンドラインでブレードを使用するパターンで試しますが、もちろんIDEで提供されるツールを利用することもできます。正しいホストを上書きできるよう、フラグメントバンドルバージョンを選択してください。ポータル・ソースからlogin.jspページをコピーします。page...%>非常にシンプルです。実際に表示部分は実装していませんが、今回の記事では割愛しています。"Installed"になっていると思います。このステータスはJSPフラグメントが動作するのに適切なステータスではないので、このままでは動作していません。依存関係の追加OSGiがフラグメントバンドルをどのように処理するか、という点に戻る必要があります。OSGiがフラグメントをロードするとき、フラグメントバンドルのMANIFEST.MFアイテムはホストバンドルからのアイテムとマージされます。build.gradleへの依存関係をリストアップする必要があり、BNDは正しいImport-Package宣言を最後のMANIFEST.MFファイルに追加します。次に、フレームワークが私のフラグメントバンドルをロードするとき、私のフラグメントのImport-Packageは、ホストバンドルのImport-Packageに追加され、すべてがうまくいくはずです。ブレードによって作成されたJSPフラグメントバンドルは、build.gradleファイルにリストされた依存関係を持っていません(実際は完全に空です)。したがって、依存関係を追加してみましょう。"2.1.1"}ホストバンドルから欠落している依存関係を追加するだけです。ホストバンドルには、取り込む予定のサービスがあります。ビルド後、JARファイルを展開してMANIFEST.MFファイルを確認すると、Import-Package宣言があることを確認できました。SCRがロード中に実際にマージを実行する場合は、動作するはずです。新しいJSPフラグメントバンドルをデプロイし、バンドルステータスをGoGoで確認すると、「Resolved」と表示されます。これでばっちりです!参照を挿入するポータルにログインしようとすると、「ポートレットは一時的に使用できません」というメッセージが表示され、ログファイルにはNullPointerExceptionと大きなスタックトレースが記録されます。login.jspはサービスに依存するが設定されていないため、ログイン・ポートレットは完全に壊れてしまっています。共有したJSPの変更をチェックすると、レンダリング要求の属性からサービスインスタンスが取得されます。ホストバンドルを最初に挿入するように変更することができない場合、どうすればそこに入るのでしょうか?PortletFilterインターフェイスを実装する新しいコンポーネント、特にRenderFilterを使用して、別のOSGiモジュールを使用してこれを行います。_memberRequestLocalService;}ポートレット・フィルターを使用してレンダー要求をインターセプトしています。レンダリングを完了するためにフィルタチェーンを呼び出す前に、リクエスト属性にサービスを注入します。フラグメントバンドルのJSPページが使用されると、その属性が設定され、準備が整います。新しいコンポーネントをビルドして展開します。起動したら、ブラウザをリフレッシュしてログインします。ログイン・ポートレットが再び表示されます。サービス参照がnullではなく、JSPオーバーライドで使用できることを証明しています。まとめここまで到達するために、だいぶ回り道しましたが、JSPフラグメントバンドルを作成してポータルJSPをオーバーライドする方法、フラグメントバンドルに依存関係を追加して、ホストバンドルに依存関係として追加する方法、ポートレット・フィルタ・バンドルを使用して、サービス参照をリクエスト属性に挿入することで、JSPページで使用できるようにします。2つの異なるバンドルjarですが、確かにこれで目的は達成できますまた、SCRとは何か、フラグメントバンドルがどのように動作するか、OSGiバンドルjarの内部構造とBNDがその構築に果たす役割についていくつか紹介しました。DXPで開発する際は役立つ便利な情報だったのではないかと思います。JSPフラグメントバンドルのための新しい道がいくつか開かれました。下記の概要にしたがえれば問題ないでしょう。ブログのプロジェクトコードはこちら:https://github.com/dnebing/jsp-fragment本記事は以上です。protected]までご連絡くだい。これまで発信してきた日本語による技術コンテンツを、Qiitaでお読みいただけます。よろしければそちらの記事も合わせてご役立てください。Doorkeeperのライフレイコミュニティメンバー大歓迎!コーポレートブログの技術コンテンツ更新情報など定期的におとどけしています。)分野のマジック・クアドラントにおいて、リーダーに選出されました。ガートナーは、ガートナー・リサーチの発行物に掲載された特定のベンダー、製品またはサービスを推奨するものではありません。最高のレーティング又はその他の評価を得たベンダーのみを選択するようにテクノロジーユーザーに助言するものではありません。ガートナー・リサーチの発行物は、ガートナー・リサーチの見解を表したものであり、事実を表現したものではありません。ガートナーは、明示または黙示を問わず、本リサーチの商品性や特定目的への適合性を含め、一切の責任を負うものではありません。