メインコンテンツまでスキップ

開発のカスタマイズ方針

ここでは、プロコード開発(スクラッチ開発)におけるカスタマイズの基本方針および実装方法について説明します。あわせて、保守性やバージョンアップへの追従性を考慮した実装上の考え方についても説明します。

カスタマイズの基本方針

intra-mart Accel Platformでは、すべての機能が「モジュール」単位で構成されています。プロコード(スクラッチ開発)におけるカスタマイズでは、製品ソースを直接編集せず、差分をユーザモジュールとして実装することを基本方針としています。

製品ソースを直接編集すると、intra-mart Accel Platformのバージョンアップやアップデートへの追従性が低下し、機能強化や機能追加モジュールといった継続的なアップデートの恩恵を受けにくくなります。そのため、継続的なアップデートを適用しやすい構造を維持することが、システムの保守性の観点から重要となります。

カスタマイズの基本構造と流れ

intra-mart Accel Platformでは、標準のベースモジュールに対してユーザモジュールを拡張ポイント経由で組み込むことで機能拡張を行います。

カスタマイズはユーザモジュール単位で実施し、ユーザモジュール内ではスクリプト開発およびJavaベース(SAStruts/JavaEE/TGFW)による実装を行います。これらの拡張は、設定ファイルを用いて拡張ポイントに紐付けることで、ベースモジュールに組み込まれます。

なお、intra-mart Accel Platformのアップデートはモジュール単位で実施されるため、カスタマイズ部分をユーザモジュールとして分離して管理する構成が推奨されます。

参考

IM-Jugglingのプロジェクト詳細画面では、ベースモジュールやユーザモジュールの構成を一覧で確認できます。詳細は「intra-mart全体像の把握 > IM-Jugglingのモジュール構成例」を参照してください。

カスタマイズ手段を選択する

カスタマイズの基本構造を踏まえ、まずカスタマイズ手段を選択します。主なカスタマイズ手段として、以下のような種類があります。

カスタマイズ手段カスタマイズ対象用途
スクリプト開発モデル画面・ビジネスロジック画面やビジネスロジックの変更、既存機能の軽微な振る舞い変更、バージョンアップ追随を重視する場合
Plugin/拡張ポイント  フレームワーク拡張イベントフック的な処理追加、標準拡張ポイントが提供されている機能の拡張など
ServiceLoader実装コンポーネントの差し替え   特定APIの内部ロジックを変更する場合、Pluginでは対応できない低レイヤ処理など
クラス差し替え  Javaクラスの直接上書き他手段で実現できない場合の一時的な回避、緊急パッチ、暫定対応(恒常利用は非推奨)

上記のカスタマイズ手段のうち、スクリプト開発モデルPlugin/拡張ポイントServiceLoaderについては、製品のバージョンアップへの追従性や保守性を考慮した標準的な拡張手段として位置付けられています。一方、クラス差し替えについては、製品のバージョンアップ時に上書きされる可能性があるため、通常は利用せず、暫定的な手段として扱ってください。

ユーザモジュールとしてカスタマイズを実装する

カスタマイズは、基本的にスクリプト開発モデルPlugin/拡張ポイントServiceLoaderのいずれかの方法を用いて、ユーザモジュール単位で実装します。ユーザモジュールとして管理することで、依存関係や対応バージョンを明確にできるほか、IM-Jugglingを利用した自動展開や処理順序の制御が可能になります。また、環境間での可搬性が向上し、安定した運用につながります。

注意

ユーザモジュールを作成する際は、カスタマイズ対象となるモジュールとの依存関係を必ず定義してください。依存関係が正しく設定されていない場合、対象モジュールより先に別のモジュールが展開され、意図した上書き処理が行われない可能性があります。

参考

ユーザモジュールの仕組みや、モジュール開発に関する詳細は、「ユーザモジュール開発ガイド」を参照してください。

カスタマイズ対象ファイルを配置する

変更対象の製品標準ファイルをコピーし、e Builderのユーザモジュール用プロジェクトに配置します。配置先はファイル種別ごとに異なります。

  • 静的ファイル(HTML、画像、CSS、JavaScriptなど)
    src/main/webapp配下の該当パスに配置します。

    • 例:画面/mypage/index.htmlを変更する場合、src/main/webapp/mypage/index.htmlに配置
  • JSP/JSSP
    スクリプト開発モデルによるカスタマイズを行う場合、src/main/webapp/WEB-INF/jssp/...または該当パスに配置します。

  • plugin.xml
    Plugin/拡張ポイントによるフレームワーク拡張を行う場合、プラグイン定義を上書きするため、src/main/webapp/WEB-INF/plugin/<対象プラグインディレクトリ>/plugin.xmlに配置します。

  • 展開順の影響により、標準のplugin.xmlが優先される場合があるため、module.xmlに依存関係を設定してください。
  • META-INF/services
    ServiceLoaderによるAPI実装の差し替えを行う場合、src/main/webapp/WEB-INF/classes/META-INF/services/に、実装クラス名を記述したファイルを配置します。

  • Javaクラス
    クラスの差し替えを行う場合、差し替え対象のクラスと同じパッケージ構成で、コンパイル済みの.classファイルを配置します。

    • 配置先:src/main/webapp/WEB-INF/classes/{パッケージディレクトリ}/
    • 例:jp.co.intra_mart.foo.Barを差し替える場合、src/main/webapp/WEB-INF/classes/jp/co/intra_mart/foo/Bar.classに配置
  • WEB-INF/classesに配置されたクラスは、WEB-INF/lib内のJARより優先して読み込まれます。

コピーしたファイルをカスタマイズする

コピーしたファイルに対して、各カスタマイズ手段に応じた方法で変更を行います。以下に、代表的なカスタマイズ方法の概要を示します。

スクリプト開発モデル

intra-martでは、製品標準ファイル(WARファイル直下やベースモジュール内のファイル)は直接編集せず、カスタマイズ領域のディレクトリに配置したファイルで上書きする方式が推奨されています。ディレクトリは上位のものが優先して読み込まれるため、製品の再デプロイやパッチ適用時に標準ファイルが上書きされる影響を最小限に抑えることができます。

スクリプト開発モデルでは、JavaScriptServerPage(JSSP)、クライアント静的リソース、Javaクラス、メッセージ・プロパティ、SQLプロパティなど、ファイル種別ごとに配置先や上書き方法が異なります。いずれも、カスタマイズ領域に配置したファイルがベースモジュールより優先して読み込まれます。

JSSPのソースコードを配置するディレクトリは、標準で以下の4種類があります。

ディレクトリ説明カスタマイズ可否
jssp/src独自開発のアプリケーションを配置するディレクトリ。主にインタプリタで動作する◎(主に使用)
jssp/product/src製品/拡張機能に関するソースコードが配置されるディレクトリ
jssp/compatible/src互換用モジュールのソースコードが配置されるディレクトリ  
jssp/platform/srcintra-mart Accel Platform本体のソースコードが配置されるディレクトリ×(直接修正しない)  

これらのディレクトリは、実行時にsrcproductcompatibleplatformの順で検索されます。読み込み順序は、conf/im_jssp_config.xmlに定義されています。

たとえば、プラットフォーム本体のソースコードをカスタマイズする場合は、jssp/platform/src配下の対象ファイルをjssp/src配下にコピーし、そのコピーを修正します。これにより、プラットフォーム本体を変更することなくカスタマイズを適用できます。

「jssp/platform/src/foo/bar/baz.js
↓ カスタマイズ対象のソースコードをコピー
「jssp/src/foo/bar/baz.js

Plugin/拡張ポイント

intra-martが提供する公式の拡張ポイントに処理を差し込む(プラグイン化する)方法です。設定ファイルで拡張処理を定義し、本体コードを変更せずに機能を追加できる点が特徴です。

拡張ポイント(extension point)とは、製品が用意した処理の差込口です。拡張ポイントごとに、登録可能なプラグイン(処理)が決まっています。カスタマイズは、以下の手順で有効になります。

  • プラグイン(Javaクラス)を作成する
  • plugin.xmlに定義し、拡張ポイントへ登録する
  • Webアプリケーションに配置して再起動する

ワークフローの処理対象者プラグインや代理設定など、多くの機能は拡張ポイントを通じて差し替えや追加が可能です。

<基本的な手順>

(1) 拡張ポイントIDの特定

ドキュメントまたはアプリケーションのWEB-INF/plugin配下(plugin.xml)から、利用可能な拡張ポイントIDやプラグインIDを確認します。

  • 例:ワークフローの処理対象者(動的承認)は、jp.co.intra_mart.workflow.plugin.authority.node.dynamic
  • 例:ワークフローの確認ノードは、…node.confirmなど
(2) Javaクラスの作成

拡張する処理に応じたインターフェイスを実装する、または製品が提供する公開APIを利用します。

  • 例:ワークフロー処理対象者プラグインでは、IWorkflowAuthorityExecEventListenerを実装するクラス
  • 実装は可能な限りステートレス(状態を保持しない)としてください。
  • static変数やメンバ変数でSpring/Repositoryを保持すると、予期しない挙動の原因となります。
(3) plugin.xmlの作成

WEB-INF/plugin/<拡張ポイントID>/<プラグインID>/plugin.xmlに配置します。plugin.xmlには、拡張ポイントID、プラグインID、実装クラス名、パラメータ定義などを記載します。

  • 既存のplugin.xmlを参考にしてください。
(4) ビルドおよび配置

実装クラスをWEB-INF/classesに配置するか、JAR化してWEB-INF/libに配置します。あわせて、plugin.xmlを所定のディレクトリに配置します。プラグインは起動時に読み込まれるため、アプリケーションコンテナ(Resin、Tomcatなど)を再起動して反映させます。

(5) ワークフローなどへの設定

対象のノード・画面・処理に対して、プラグインIDを設定します。プラグインIDは、管理画面やAPIで設定するほか、ApplyManagerDCNodeConfigModelsを作成して適用する方法もあります。

  • ワークフローでは、ノード種別に応じた拡張ポイント(dynamic/confirmなど)を使用してください。
(6) 動作確認・ログ確認

system.logDEBUGレベルに設定し、プラグインの呼び出しログを確認します。

  • 例:ワークフロー処理対象者プラグインの場合、[Listener]処理対象者展開ロジック開始、拡張ポイント…、プラグインID…といったログが出力される
  • 非同期処理(到達処理など)が含まれる場合は、非同期タスクの登録やスレッド実行に関するログも確認してください。
  • 非同期タスクの登録からスレッド実行まで、時間差が発生する場合があります。
ServiceLoader

JavaのServiceLoaderの仕組みを利用して、 APIの実装クラスを差し替える方法です。ServiceLoaderは、インタフェース(または抽象クラス)を実装したクラスを、実行時に検出して利用するJavaの標準機能です。

製品側がServiceLoaderを用いて実装を探索する場合、標準実装の代わりに独自の実装クラスを提供することで、処理を差し替えることができます。APIの呼び出し元を変更せずに、実装のみを差し替えることができる点が特徴です。一方で、製品によっては差し替えが難しい箇所があるため、十分なテストを実施してください。

クラス差し替え

Servletのクラスロード順序を利用し、libより先に読み込まれるclasses配下にJavaクラスを配置して差し替える方法です。製品クラスを直接置き換えることができますが、この方法はWARファイルの再ビルドや再デプロイ時に、classes配下の内容が初期状態で再配置される可能性があります。

注意

手動で差し替えたクラスが上書きされ、意図せず変更内容が失われる恐れがあります。また、この方法は標準的なカスタマイズ手順から外れるため、変更内容の管理や引き継ぎが難しくなり、保守性の低下につながります。他の方法では実現できない場合の一時的な回避や、緊急パッチなどの限定的な対応とし、恒常的な運用は避けてください。

依存関係を設定する(展開順の制御)

カスタマイズしたファイルを含む製品モジュールを、依存先として設定します。これは、モジュールの展開順を制御するために必須の設定です。カスタマイズ対象が既存の製品モジュール(例:jp.co.intra_mart.im_workflow)を上書きする場合は、module.xmlに依存関係を定義します。

  • 例(抜粋): jp.co.intra_mart.im_workflow 8.0.20
    本設定により、ユーザモジュールがベースモジュールより後に展開され、plugin.xmlなどの上書きが正しく適用されます。
注意

依存関係の指定ミスや不足があると、意図した順序で展開されない可能性があります。文字コードやエンコード方式にも注意してください。

e Builderでユーザモジュールをエクスポートする

e Builderで該当のモジュールプロジェクトを選択し、ユーザモジュール(.imm)をエクスポートします。エクスポートすると、プロジェクト単位でユーザモジュールが出力されます。出力された.immファイルはZIP形式のため、一度解凍して以下の内容を確認します。

  • src配下のファイルが正しく含まれているか(特にWEB-INF/classesWEB-INF/plugin配下)
  • 不要な古いJARファイルが混入していないか

IM-Jugglingでユーザモジュールを取り込む

(1) ユーザモジュールの取り込み

IM-Jugglingの管理画面から[ユーザモジュール取り込み]を選択し、.immファイルを登録します。取り込み時は、モジュールの依存関係やバージョンを確認し、画面の案内に従って設定を行います。

(2) WARファイルの出力

IM-Jugglingに取り込んだユーザモジュールを有効化し、WARファイルを出力します。ユーザモジュールは、製品ベースモジュールとともに1つのWARファイルにまとめられます。

(3) 出力内容の確認

出力されたWARファイルはZIP形式のため、一度解凍して以下の内容を確認します。

  • WEB-INF/classesにクラスファイルが配置されているか(例:WEB-INF/classes/jp/.../Bar.classが存在するか)
  • WEB-INF/pluginにプラグイン定義が反映されているか(例:WEB-INF/plugin/.../plugin.xmlが任意の内容か)
  • その他、カスタマイズ対象のファイルが意図したパスに配置されているか

Resinサーバへデプロイする

(1) WARファイルの配置

生成したWARファイルをサーバへ配置します。resin deploy myapp.warを実行するか、webappsフォルダへWARファイルをコピーしてください。

(2) サーバの再起動またはリロード

サーバを再起動、またはアプリケーションのリロードを行い、変更内容を反映させます。

(3) ログの確認

反映後は、system.logを確認し、起動時のプラグイン読み込みログやWARNING/ERRORの有無を確認します。

動作確認を行う

該当する画面や処理を起動し、カスタマイズした内容が反映されていることを確認します。

メモ

classesディレクトリでのクラス差し替えを行う場合、差し替えたクラスにログ出力を追加しておくと、動作確認が容易になります。

メッセージプロパティをカスタマイズする

メッセージプロパティを変更する場合、ユーザモジュールとして実装する方法のほかに、IM-Jugglingプロジェクトのconf/messageに配置することで簡易的に上書きできます。

製品内の文言や表示メッセージは、主にメッセージプロパティファイルで管理されています。これらの内容は、IM-Jugglingプロジェクトに配置することでカスタマイズできます。カスタマイズする場合は、製品標準ファイルと同じディレクトリ構成でファイルを配置することで、WARファイルの作成時に反映されます。

IM-Jugglingに配置する

  1. カスタマイズ対象の製品標準のメッセージプロパティファイルをコピーし、任意の場所に配置します。
  2. コピーしたプロパティファイルを編集し、文言や表示メッセージを変更します。
  3. IM-Jugglingプロジェクト内のconf/message配下に、製品標準と同じディレクトリ構成でファイルを配置します。
注意

マルチバイト文字を含む場合は、Unicodeでのエンコード/デコード処理を行うか、専用のプロパティファイルエディタで編集してください。