Eclipse RCP (Rich Client Platform) を使用すると、アプリケーションを構築することができます。RCP では動的なプラグイン・モデルをベースにリッチなアプリケーションを構築し、共通のツールキットと拡張ポイントを使って UI を作成します。Eclipse RCP は、オープン・ツールの開発で広く用いられています。
RAP (Rich Ajax Platform) プロジェクトでは、Eclipse 開発モデル、プラグイン、そして Java のみの API を使って Ajax 対応のリッチな Web アプリケーションを構築することができます。RAP の目的は、最小限の変更を加えるだけで、RCP アプリケーションを Web ブラウザーで実行できるようにすることです。
RAP と RCP のインターフェースは共通していますが、それぞれがベースとしている実装は大きく異なります。RAP は SWT API の代わりとして、Tomcat のようなサーブレット・コンテナーで稼働する RWT を実装します。クライアントが RWT にアクセスするには、Internet Explorer や Chrome などの標準 Web ブラウザーを使用することができます。
RAP アプリケーションと RCP アプリケーションとでは、これらのアプリケーションが使用されるユーザー環境にも違いがあります。デスクトップ・アプリケーションである RCP は、一度に 1 人のユーザーしか使用することができません。その一方、RAP アプリケーションは Web ベースのプログラムであり、複数のユーザーが同時にアクセスすることができます。RAP がベースとする Equinox は、サーバー・サイドの OSGi およびランタイム・バンドルです。Web アプリケーションごとに 1 つの OSGi インスタンスが、アプリケーションのスコープで実行されます。RCP とは対照的に、RAP はユーザー・セッションと、ユーザー・セッション間で共有されるバンドルを扱わなければなりません。
この記事では RAP の主要な機能を紹介し、RAP を使って RCP アプリケーションを Web にマイグレーションする方法を説明します。記事で使用するサンプル・ソース・コードは、ここからダウンロードすることができます。
RAP は、単一のコード・ベースからリッチ・クライアント・アプリケーションおよび Web アプリケーションの両方を開発できることで人気を得ています。シングル・ソーシングとも呼ばれるこの開発手法では、既存の RCP 開発のスキルとコード・ベースを Web ベースの RAP アプリケーションに再利用することができます。現行バージョンの RAP 1.3.x では、既存の RCP コードの 70 パーセントから 90 パーセントを変更せずにそのまま RAP 環境で再利用することができます。
RCP と RAP が使用する API、機能、UI ライブラリー、拡張ポイント、そしてユーザー環境には、以下の違いがあります。
- API: RAP のバージョン 1.3.x では、RCP のすべての API が使用できるわけではありません。使用できない API に該当するのは、例えば GC (Graphics Context)、MouseMove イベント、FileDialog などです。RAP は Web 特有の要件に対処しなければならないことから、
PhaseListener、ISessionStoreなどの RAP 独自の API もあります。異なる API に対処するには、以下の推奨案を検討してください。- 問題となるインターフェースをホスト・プラグインに定義します。
- 問題となるインターフェースを異なるフラグメントに実装する新しいクラスを定義し、それぞれのプラットフォームに応じた方法で問題を解決します。
- プラットフォームに固有の実装を Java リフレクションによって実行時にロードします。
サンプル・ソース・コードは、「シングル・ソーシングの例」のセクションに記載します。
- UI ライブラリー: RCP と RAP がターゲットとするプラットフォームは異なるため、それぞれが利用する UI ライブラリーも異なります。RCP と RAP に共通のコードが含まれるホスト・プラグインには、両方のプラットフォームの UI ライブラリーへの依存関係が必要です。例えば、RCP 用の
org.eclipse.uiプラグインと RAP 用のorg.eclipse.rap.uiプラグインは、両方ともホストの必須プラグインとしてインポートしなければなりません。異なるターゲット・ランタイムを使用する場合には、コンパイル時のエラーを防ぐために、「Properties (プロパティー)」の下にある「Optional (オプション)」チェック・ボックスを有効にします (図 1 を参照)。このようにすることで、RAP/RCP ランタイムは実行を開始する際に適切なライブラリーをロードします。
図 1. オプションの依存関係
- 拡張ポイント (E-P): 現時点では、RCP の E-P のなかには RAP で使用できないものもあります (
bindingsやhelpSupportなど)。Web 特有の要件により、RAP にはentrypointおよびthemesなどの E-P が追加されています。E-P の違いに対処して RCP と RAP に同じコード・ベースを使用できるようにするために、OSGi フラグメントが導入されました。フラグメントとは、別のバンドルを拡張する特殊な OSGi バンドルのことです。これらの拡張バンドルは、実行時にマージすることができます。それにはまず、RCP と RAP に共通のコードを収容するホスト・プラグインを定義します。次に、RAP と RCP ごとに別個のフラグメントを作成し、そこに RAP と RCP それぞれのプラットフォーム固有のコードを収容します。実行時には、該当するどちらか一方のフラグメント (RAP または RCP) だけが、ホスト・プラグインと一緒にインストールされるため、該当するフラグメントにプラットフォーム固有の E-P 拡張を移すことができます。こうすれば、バンドルの構造は手付かずのままになります。
- マルチユーザー環境: RCP ではシングルトン・パターンが広く使用されています。ただし、複数のユーザーが同時にアクセスできる Web ベースのアプリケーションには、セッション・ベースのシングルトン・パターンが必要となります。そこで RAP に用意されているのが、
SessionSingletonBaseという基底クラスです。このクラスは、セッションごとのシングルトン実装を提供し、異なるユーザーの間でアプリケーションの状態が共有されないようにします。セッション・シングルトンは、RWT 特有のシングルトンです。このシングルトンを使用すれば、セッション・スコープ内の固有のインスタンスにアクセスすることができます。つまり、
getInstance(Class)は、ある特定のユーザー・セッションのコンテキストでは常に同じオブジェクトを返しますが、別のユーザー・セッションでは異なるインスタンスを返すことになります。セッション・シングルトン・クラスを実装するには、シングルトン・インスタンスの適切なスコープを処理する
SessionSingletonBase#getInstance()を呼び出す必要があります。リスト 1 に、このパターンを示します。RAP に関する FAQ については、「参考文献」を参照してください。
リスト 1. セッション・シングルトンの例package com.ibm.msdk.ui.configWas; import org.eclipse.rwt.SessionSingletonBase; public class SampleSessionSingleton{ private SampleSessionSingleton(){} public static SampleSessionSingleton getInstance(){ return (SampleSessionSingleton)SessionSingletonBase .getInstance(SampleSessionSingleton.class); } }
このセクションでは、HTML ビューアーのサンプル RCP アプリケーションを用いて、シングル・ソーシングを実現する方法を詳しく説明します。記事で使用するサンプル・ソース・コードは、ここからダウンロードすることができます。サンプル・アプリケーションには HTML ファイルを表示するビューがあり、このビューのツールバーの「Open (開く)」ボタンを使って HTML ファイルを開くことができます (図 2 を参照)。
図 2. RCP HTML ビューアーの例
サンプルでは、ブラウザー・ウィジェットを使用して HTML ファイルを表示します。この機能を実装するためには、com.ibm.msdk.example という名前のサンプル・プラグインを作成する必要があります。
- RCP プラットフォームに固有のコードを識別します。
前述のとおり、サンプル・プラグインには RAP/RCP プラットフォームに固有のコードが含まれています。まずは、サンプル・プロジェクトから共通コードを抽出してください。共通コードを分析することで、RAP ではサポートしていない RCP HTML ビューアーの API、つまり (
com.ibm.msdk.example.actionパッケージに含まれる)FileDialog#openが見つかります (リスト 2 を参照)。
リスト 2. RCP プラットフォームに固有のコードimport org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchWindow; import com.ibm.msdk.example.utils.HtmlFileReader; public class ImportHtmlAction extends Action { public static final String ACT_IMPORT_FILE = "ACT_IMPORT_FILE"; private IWorkbenchWindow workbenchWindow; /** * Constructs an instance of <code>ImportHtmlAction</code> by given * text and <code>IWorkbenchWindow</code>. * @param text * @param workbenchWindow */ public ImportHtmlAction(String text,IWorkbenchWindow workbenchWindow){ super(text); this.workbenchWindow = workbenchWindow; } /** * Creates a file dialog for opening a new file,calls the method * {@link HtmlFileReader#fetchHtmlContents(String)} to fetch the contents * of the passed HTML file. Then fires the listener of <code>HTMLView</code> * to refresh the contents of the view. */ @Override public void run(){ Shell shell = workbenchWindow.getShell(); FileDialog fileDialog = new FileDialog(shell,SWT.OPEN); String filePath = fileDialog.open(); String htmlContents = null; if(filePath != null) htmlContents = HtmlFileReader.fetchHtmlContents(filePath); firePropertyChange(ACT_IMPORT_FILE, null, htmlContents); } }
RAPでは、ファイルを開くよりも、ファイルをアップロードするほうが賢明です。「RAP Upload Project」ではそのようなアップロード関数を提供しており、RAP の CVS リポジトリーからダウンロードできるようになっています (sandbox/org.eclipse.rwt.widgets.upload)。
- RCP および RAP それぞれのフラグメントを作成します。
com.ibm.msdk.exampleプラグインは RAP プラットフォームと RCP プラットフォームの両方をターゲットとするため、「必須プラグイン」としては、この 2 つのプラットフォームに必要なバンドルをインポートしなければなりません。例えば UI バンドルとしては、org.eclipse.ui(RCP) とorg.eclipse.rap.ui(RAP) の両方が必要です。ターゲット・プラットフォームの違いによるコンパイル・エラーが発生しないようにするには、プラグインの「Properties (プロパティー)」で、異なる UI バンドルの依存関係を「Optional (オプション)」として指定します (図 3 を参照)。
図 3. オプション依存関係
これで、プラットフォーム・ランタイム環境 (RCP または RAP) は適切なバンドルをロードすることになります。ターゲット・プラットフォームは 2 つあるため、それぞれのプラットフォーム固有のコードを収容する 2 つのフラグメントを新規に作成しなければなりません。これらのフラグメントのホスト・プラグインのプロパティーは、図 4 に示されているように
com.ibm.msdk.exampleプラグインに設定します。
図 4. ホスト・プラグインを com.ibm.msdk.example に設定する
- 特殊な関数を処理するための抽象クラスを作成します。
RAP には FileDialog ウィジェットがありません。そのため、クライアント・サイドからサーバーにファイルをアップロードすることが可能な新しいウィジェットを使用しなければなりませんが、幸い RAP の CVS により、カスタマイズ済みアップロード・ウィジェットをリポジトリー・ロケーションの URL (pserver:anonymous@dev.eclipse.org:/cvsroot/rt) からダウンロードできるようになっています (このウィジェットは org.eclipse.rap/sandbox/org.eclipse.rwt.widgets.upload にあります)。アップロードされたウィジェットを正しく機能させるには、
org.apache.commons.fileuploadおよびorg.apache.commons.ioプラグインが必要です。この 2 つはどちらもリポジトリー・ロケーションの URL、pserver:anonymous@dev.eclipse.org:/cvsroot/tools からダウンロードすることができます。これらのプラグインは、org.eclipse.orbit/ にあります。CVS をダウンロードに使用する方法についての詳細は、「参考文献」を参照してください。- 必要なプラグインを RAP フラグメントに追加します (図 5 を参照)。
図 5. アップロード・プラグインを依存関係に追加する
- ホスト・プラグイン内には、RAP プラットフォームと RCP プラットフォームとの間で共通していない特殊な関数を扱うための抽象クラスを作成する必要があります。そこで、
doViewHtml()という名前の抽象メソッドを定義します (リスト 3 を参照)。
リスト 3. Action の抽象クラス/** * */ package com.ibm.msdk.example.actions; import org.eclipse.jface.action.Action; import org.eclipse.ui.IWorkbenchWindow; /** * @author Minghai.Wang * @version 1.0 2010-10-26 * @since JDK1.6 * @email wminghai@cn.ibmm.com */ public abstract class AbstractViewHtmlAction extends Action { protected IWorkbenchWindow workbenchWindow; public static final String ACT_IMPORT_FILE = "ACT_IMPORT_FILE"; public static final String INSTANCE_CLASS = "com.ibm.msdk.example .actions.ViewHtmlAction"; /** * Constructs an instance of <code>AImportHtmlAction</code> by given * <code>IWorkbenchWindow</code>. * * @param workbenchWindow */ public AbstractViewHtmlAction(IWorkbenchWindow workbenchWindow) { this.workbenchWindow = workbenchWindow; } public void run() { doViewHtml(); } /** * Abstracts the method for viewing the given HTML file. * <p> * It is different between RCP platform and RAP platform. * <ul> * <li>In the RCP fragment,open a file dialog and select a HTML file that * will be parsed, and then show it.</li> * <li>In the RAP fragment,upload a parsing HTML file, then show it. * </ul> */ public abstract void doViewHtml(); /** * @return the workbenchWindow */ public IWorkbenchWindow getWorkbenchWindow() { return workbenchWindow; } /** * @param workbenchWindow * the workbenchWindow to set */ public void setWorkbenchWindow(IWorkbenchWindow workbenchWindow) { this.workbenchWindow = workbenchWindow; } }
doViewHtml()アクションを呼び出すには、ホスト・プラグインの呼び出し側の部分に変更が必要です。このメソッドは、元のクラスではリスト 4 のようになっています。
リスト 4. 元の HtmlContentsView クラスでのメソッドpublic class HtmlContentsView extends ViewPart implements IPropertyChangeListener { ... ... /** * Fills the tool bar of the HTML view with a importing HTML action. A * listener is added to the created action of importing HTML view. */ protected void fillToolBarAction() { ImportHtmlAction importHtmlAct = new ImportHtmlAction("Open...", getViewSite().getWorkbenchWindow()); IToolBarManager toolBarManager = getViewSite().getActionBars() .getToolBarManager(); toolBarManager.add(importHtmlAct); importHtmlAct.addPropertyChangeListener(this); } ... }
新しいフラグメントのアクションを取得するには、
com.ibm.msdk.exampleプラグインの HtmlContentsView.java で Java リフレクションを使用します (リスト 5 を参照)。すると、RCP フラグメントと RAP フラグメントに、同じ名前のサブクラスが作成されます。このようにして、ランタイム・プラットフォームが異なっていても (RCP または RAP)、適切なフラグメントがロードされ、その状況に即したdoViewHtml()アクションが呼び出されるようにします。
リスト 5. 新しい HtmlContentsView クラスでのメソッドpublic class HtmlContentsView extends ViewPart implements IPropertyChangeListener { ... /** * Fills an instance of <code>AbstractViewHtmlAction</code> * that is created by Java reflection. */ protected void fillToolBarAction() { try { Class<?> clazz = Class .forName(AbstractViewHtmlAction.INSTANCE_CLASS); Constructor<?> cons = clazz .getConstructor(IWorkbenchWindow.class); AbstractViewHtmlAction viewHtmlAction = (AbstractViewHtmlAction) cons.newInstance(getViewSite().getWorkbenchWindow()); IToolBarManager toolBarManager = getViewSite().getActionBars() .getToolBarManager(); toolBarManager.add(viewHtmlAction); viewHtmlAction.addPropertyChangeListener(this); // Add an action for viewing singleton info. ViewSingletoInfoAction viewSingleton = new ViewSingletoInfoAction( getViewSite().getWorkbenchWindow()); toolBarManager.add(viewSingleton); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } ... }
- 必要なプラグインを RAP フラグメントに追加します (図 5 を参照)。
- RAP および RCP フラグメントに実装します。
プラットフォームに固有の関数を処理する抽象クラスを定義した後は、この抽象メソッドを RCP フラグメントと RAP フラグメントのそれぞれに、異なる方法で実装します。RCP フラグメントに作成するのは、抽象クラス
AbstractViewHtmlActionを継承する新規クラスです (リスト 6 を参照)。この新規クラスにより、FileDialog で HTML ファイルを開くための抽象メソッドを実装します。
リスト 6. RCP での AbstractViewHtmlAction の実装public class ViewHtmlAction extends AbstractViewHtmlAction { ... /** * Creates a file dialog for opening a new file,calls the method * {@link HtmlFileReader#fetchHtmlContents(String)} to fetch the * contents of the passed HTML file.Then fires the listener of * <code>HTMLView</code> to refresh the contents of the view. */ @Override public void doViewHtml() { Shell shell = workbenchWindow.getShell(); FileDialog fileDialog = new FileDialog(shell,SWT.OPEN); String filePath = fileDialog.open(); String htmlContents = null; if(filePath != null) htmlContents = HtmlFileReader.fetchHtmlContents(filePath); firePropertyChange(ACT_IMPORT_FILE, null, htmlContents); } ... }
RAP フラグメントの抽象メソッドの実装は、RCP とは異なります。RAP の場合には、「アップロード」ウィジェットによって HTML ファイルを Web サーバーに転送してから、ファイルを開きます (リスト 7 を参照)。
リスト 7. RAP での AbstractViewHtmlAction の実装public class ViewHtmlAction extends AbstractViewHtmlAction { ... /** * Opens a new shell for uploading a HTML file, * creates the widgets. */ @Override public void doViewHtml() { Display display = Display.getDefault(); Shell shell = new Shell(display, SWT.PRIMARY_MODAL | SWT.CLOSE | SWT.RESIZE); shell.setText("Upload a HTML file"); shell.setLayout(new GridLayout()); shell.setSize(450, 60); // Creates the control in the shell. createControl(shell); shell.layout(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } } /** * * @param shell */ protected void createControl(final Shell shell){ Upload upload = new Upload(shell,SWT.NONE,Upload.SHOW_UPLOAD_BUTTON); upload.setUploadButtonText("Upload"); upload.setBrowseButtonText("Location..."); GridDataFactory.fillDefaults().grab(true, false).applyTo(upload); upload.addUploadListener(new UploadListener(){ ... ... }); } ... }
- マルチユーザー・サポート
RAP プラットフォームでは、セッション・シングルトンによってセッション・スコープ内の固有インスタンスにアクセスします。このサンプル・アプリケーションは、RAP ではセッション・シングルトンを使用し、RCP では共通シングルトンを使用する事例となります。
- ホスト・プラグインに
ExampleSingletonという名前のシングルトン・クラスを作成します。さらに、ISingletonProviderと名付けたインターフェースと、ImplementationLoaderと名付けたクラス・ローダーも作成します。
リスト 8. ホスト・プラグイン内のセッション・シングルトンpublic class ExampleSingleton { private final static ISingletonProvider PROVIDER; static{ PROVIDER = (ISingletonProvider) ImplementationLoader .newInstance(ExampleSingleton.class); } /** * Gets the instance of <code>ExampleSingleton</code> which has * different implementations in RAP and RCP fragment. * @return */ public static ExampleSingleton getInstance(){ return (ExampleSingleton)PROVIDER.getInstanceInternal(); } public String fetchSingtonInfo(){ return PROVIDER.fetchSingletonInfo(); } }
リスト 9. ホスト・プラグイン内のインターフェースpublic interface ISingletonProvider { Object getInstanceInternal(); /** * Fetches the singleton info,which is different * between RCP platform and RAP platform. * @return */ String fetchSingletonInfo(); }
リスト 10. ローダーpublic class ImplementationLoader { public static Object newInstance(final Class<?> type){ String name = type.getName(); Object result = null; try { result = type.getClassLoader() .loadClass(name + "Impl").newInstance(); } catch (Exception e) { e.printStackTrace(); } return result; } }
ExampleSingletonサブクラスを作成します。RAP フラグメントと RCP フラグメントの両方にISingletonProviderインターフェースを実装し、それぞれに異なるシングルトンを実装します。
リスト 11. RAP でのセッション・シングルトンの実装public class ExampleSingletonImpl implements ISingletonProvider { public Object getInstanceInternal() { return SessionSingletonBase.getInstance(ExampleSingleton.class); } ... ... }
リスト 12. RCP でのセッション・シングルトンの実装public class ExampleSingletonImpl implements ISingletonProvider { private static ExampleSingleton singleton; /* (non-Javadoc) * @see com.ibm.msdk.example.singleton * .ISingletonProvider#getInstanceInternal() */ @Override public Object getInstanceInternal() { if(singleton == null) singleton = new ExampleSingleton(); return singleton; } /* (non-Javadoc) * @see com.ibm.msdk.example.singleton * .ISingletonProvider#fetchSingletonInfo() */ @Override public String fetchSingletonInfo() { return "This message is from RCP fragment!"; } }
- ホスト・プラグインに
RAP アプリケーションのパッケージ化と Tomcat へのデプロイメント
このセクションでは、WAR ファイルを作成して Tomcat にデプロイします。また、デプロイした WAR ファイルが機能しない場合のトラブルシューティングのヒントも紹介します。
現在、Eclipse では RAP アプリケーションのビルドを直接サポートしていません。したがって今のところは、複数の Ant スクリプトとリソース・テンプレートを使って WAR ファイルを作成する必要があります。RAP の CVS に用意されている org.eclipse.rap.demo.feature に、org.eclipse.rap.demo プロジェクトを RAP アプリケーションとしてパッケージ化する WAR ファイルの作成方法が示されています。作成した WAR ファイルを変更すれば、この RAP デモ・フィーチャー・プロジェクトをサンプル HTML ビューアーで使用できるようになります。
- オンライン・バージョンの RAP Developer Guide の記述 (RAP Developer Guide を「Advanced Topics」 > 「WAR Deployment」の順に展開すると表示されるページの記述) に従って、チーム・プロジェクト・セット・ファイルをダウンロードします (「参考文献」にリンクを記載)。
- Eclipse で「File (ファイル)」 > 「Import (インポート)」 > 「Team Project Set (チーム・プロジェクト・セット)」の順に選択し、ダウンロードしたファイルの場所を入力します。
- 「Finish (完了)」をクリックします。これで、必要なプロジェクトが CVS からインポートされます。インポートされるプロジェクトには、org.eclipse.equinox.http.servletbridge、org.eclipse.equinox.servletbridge、org.eclipse.rap.demo.feature があります。
- org.eclipse.rap.demo.feature の名前を
com.ibm.msdk.example.rap.featureに変更し、以下の項目をフィーチャー・リストに追加します (図 6 を参照)。- com.ibm.msdk.example
- com.ibm.msdk.example.rap
- org.apache.commons.fileupload
- org.apache.commons.io
- org.eclipse.rwt.widgets.upload
RAP デモ・プラグインが不要であれば、フィーチャー・リストから org.eclipse.rap.demo を削除しても構いません。
- フィーチャーの ID を
com.ibm.msdk.example.rap.featureに変更します (図 6 を参照)。
図 6. HTML ビューアーのフィーチャー
- 以下の手順に従って、HTML ビューアー RAP アプリケーション全体をビルドする Ant タスクを構成して実行します。
- 「webappBuilder.xml」を開き、プロパティーの値 (27 行目) を「
com.ibm.msdk.example.rap.feature」に変更します。 - 「webappBuilder.xml」を右クリックして、「External Tools Dialog (外部ツール・ダイアログ)」を開きます (「Run As (実行)」 > 「External Tools Configuration (外部ツールの構成)」)。
- 「Ant Build (Ant ビルド)」をダブルクリックします。
- 新規エントリー「com.ibm.msdk.example.rap.feature webappBuilder.xml」を選択します。
- 「JRE」タブで、「Runtime JRE (ランタイム JRE)」を「Run in the same JRE as the workspace (ワークスペースと同じ JRE で実行)」に設定します。このように設定しないと、スクリプトは PDE Ant タスクを使用してフィーチャーをエクスポートすることができません。
- 「Run (実行)」をクリックします。
- コンソールに「
BUILD SUCCESSFUL(ビルド成功)」というメッセージが表示されるはずです。
進行状況表示バーを見ると、PDE Export タスクがまだバックグラウンドで実行中であることがわかります。このタスクが完了するまで待ってください。
- 「webappBuilder.xml」を開き、プロパティーの値 (27 行目) を「
- 以下の手順に従って、config.ini ファイルを生成します。
- org.eclipse.rap.demo に含まれる ConfigIniCreator.java という Java ファイルを開き、39 行目をリスト 13 に示す内容に変更します。
リスト 13. 変更後のコードFile file = new File( "build\\demo\\WEB-INF\\eclipse\\plug-ins" )
- ConfigIniCreator を Java アプリケーションとして起動します (Eclipse コンソールにリスト 14 に示すようなテキストが出力されます)。
リスト 14. Config.ini の例#Eclipse Runtime Configuration File osgi.bundles= com.ibm.icu.base@start,\ com.ibm.msdk.example.rap,\ com.ibm.msdk.example@start,\ org.apache.commons.fileupload@start,\ org.apache.commons.io@start,\ org.eclipse.core.commands@start,\ org.eclipse.core.contenttype@start,\ org.eclipse.core.databinding.observable@start,\ org.eclipse.core.databinding.property@start,\ org.eclipse.core.databinding@start,\ org.eclipse.core.expressions@start,\ org.eclipse.core.jobs@start,\ org.eclipse.core.runtime@start,\ org.eclipse.equinox.app@start,\ org.eclipse.equinox.common@2:start,\ org.eclipse.equinox.http.registry@start,\ org.eclipse.equinox.http.servletbridge@start,\ org.eclipse.equinox.http.servlet@start,\ org.eclipse.equinox.preferences@start,\ org.eclipse.equinox.registry@start,\ org.eclipse.help@start,\ org.eclipse.osgi.services@start,\ org.eclipse.rap.demo@start,\ org.eclipse.rap.jface.databinding@start,\ org.eclipse.rap.jface@start,\ org.eclipse.rap.rwt.q07,\ org.eclipse.rap.rwt@start,\ org.eclipse.rap.ui.views@start,\ org.eclipse.rap.ui.workbench@start,\ org.eclipse.rap.ui@start,\ org.eclipse.rwt.widgets.upload@start,\ org.eclipse.equinox.servletbridge.extensionbundle osgi.bundles.defaultStartLevel=4
- 出力されたテキストをすべてコピーして、{プロジェクト・ルート}/templates/WEB-INF/eclipse/config.ini の既存の内容を置き換えます。
- すべての RAP フラグメント (com.ibm.msdk.example.rap) から
@startを削除します。 - まず、{プロジェクト・ルート}/templates/WEB-INF/eclipse/config.ini を {プロジェクト・ルート}/build/demo/WEB-INF/eclipse/configuration/ にコピーして、既存のファイルを置き換えます。feature.xml が変更されている場合は、config.ini を生成し直す必要があります。
- com.ibm.msdk.example.rap.feature/script ディレクトリーに新規 build.xml を作成し、そのファイルに以下のスクリプトをコピーします。
リスト 15. WAR ファイルをビルドするための ANT スクリプト<?xml version="1.0"?> <project name="warbuild" default="war.gen"> <property name="war.name" value="sample.war"/> <target name="war.gen" depends="clean"> <war warfile="../${war.name}" webxml="../build/msdk/WEB-INF/web.xml"> <lib dir="../build/msdk/WEB-INF/lib" /> <lib dir="../build/msdk/WEB-INF/eclipse" prefix="WEB-INF/eclipse" /> </war> </target> <target name="clean"> <delete file="../${war.name}"/> </target> </project>
- Eclipse で「Ant Build (Ant ビルド)」として build.xml を実行します。すると HTML ビューアーの WAR ファイルとして、sample.war というファイルがプロジェクト・ルート・ディレクトリー内に生成されます (図 7 を参照)。
図 7. Eclipse ワークスペース内の sample.war
- org.eclipse.rap.demo に含まれる ConfigIniCreator.java という Java ファイルを開き、39 行目をリスト 13 に示す内容に変更します。
sample.war ファイルを Tomcat にデプロイするには、sample.war を {TOMCAT_HOME}/webapps/ にコピーします。そして Tomcat を起動し、http://localhost:8080/sample/msdkExample を指定して HTML ビューアーにアクセスします (図 8 を参照)。
図 8. sample.war を Tomcat にデプロイする
RAP は開発時に機能していても、Tomcat や WebSphere にデプロイすると機能しなくなる場合があります。このような場合には、以下の点を確認してください。
- RAP アプリケーションが build.properties ファイルを使用している場合、このファイルがエクスポートされていること、そして RAP アプリケーションで使用するすべてのライブラリーがプラグインのクラス・パスに記載されていることを確認します。
- リスト 16 の変更内容を web.xml に追加して、OSGi コンソールを使用可能にします。
リスト 16. OSGi フレームワークのコンソールを使用可能にする<init-param> <param-name>commandline</param-name> <param-value>-console</param-value> </init-param> <!-- <init-param> <param-name>commandline</param-name> <param-value>-registryMultiLanguage</param-value> </init-param> --> <init-param> <param-name>enableFrameworkControls</param-name> <param-value>true</param-value> </init-param>
コンソールに「
ss」と入力して (Tomcat の場合)、すべてのバンドルが起動されているかどうかを確認します。起動されていない場合は、「start <bundle-id>」を実行してバンドルを起動してみてください。何が欠けているかについては、スタック・トレースがヒントになる場合があります。ss による出力に、org.eclipse.equinox.servletbridge.extensionbundleがRESOVLED状態として含まれていることを確認します (図 9 を参照)。
図 9. Tomcat で起動されているバンドル
- WAR に以下のバンドルが含まれていないことを確認します。
javax.servletバンドル。javax.servletは、プラグイン・マニフェストのRequire-Bundleセクションではなく、Import-Packageセクションに記載されていなければなりません。org.eclipse.update.configuratorバンドル*.jetty.*バンドル
- WAR ファイルを再デプロイする場合は、サーブレット・エンジンの作業ディレクトリー (例えば、Tomcat の <tomcat_install>/work/Catalina/localhost/work/<webapp_name>) を必ず削除してください。
この記事では、RAP および RCP アプリケーション開発のシングル・ソーシングの概念を紹介し、シングル・ソーシング手法を使って既存の RCP アプリケーションを Web ベースの RAP アプリケーションに変換する方法を説明しました。RAP は RCP 開発者にとって、既存のコード・ベースを再利用して Web ベースのアプリケーションを作成するための強力なツールとなります。記事ではまた、RAP アプリケーションを WAR ファイルにパッケージ化する方法、そして WAR ファイルを Web コンテナーにデプロイする方法についても説明しました。
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| Project sample | workspaceExample.zip | 57KB | HTTP |
学ぶために
- RAP (Rich Ajax Platform): Eclipse 開発モデル、Eclipse ワークベンチ拡張ポイントを使用するプラグイン、そして SWT API を備えたウィジェット・ツールキットを使用して、リッチな Ajax 対応 Web アプリケーションを構築する手段となる RAP の全容を読んでください。
- RAP/FAQ (The Eclipse Foundation、2011年): RAP の FAQ を調べてください。
- CVS Howto: Anonymous CVS (The Eclipse Foundation、2011年): CVS を使用してダウンロードする方法についての詳細を学んでください。
- RAP Developer Guide: RAP 開発者向けガイドを読んでください。
- 「Rich Ajax Platform、第 1 回: 概要」(developerWorks、2007年10月) および「Rich Ajax Platform, Part 2: Developing applications」(developerWorks、2007年12月): RAP の概要、主要な概念、そして RAP が提供する高度な機能を使用する方法を学んでください。
製品や技術を入手するために
- RAP ツールと RAP ランタイム: RAP ツールおよび RAP ランタイムをダウンロードしてください。
- Eclipse for RCP and RAP developers: RCP および RAP 開発者向け Eclipse をダウンロードして、Eclipse プラグイン、RCP+RAP (Rich Client or Rich Ajax Applications)、Mylyn、そして XML エディターを作成したい開発者向けのツール一式を入手してください。
議論するために
- 今すぐ developerWorks で自分のプロフィールを作って、Ajax に関するウォッチ・リストをセットアップしてください。developerWorks コミュニティーとずっとつながっていられます。
- Web 開発に興味を持つ他の developerWorks メンバーを見つけてください。
- Web のトピックを専門とする developerWorks グループに参加して、知識を共有してください。
- Roland Barcia が彼のブログで Web 2.0 とミドルウェアについて語っています。
- developerWorks のメンバーが共有する Web のトピックに関するブックマークをフォローしてください。
- Web 2.0 Apps フォーラムで、素早く回答を得てください。
- Ajax フォーラムで、素早く回答を得てください。

Zhi Da Luo は、IBM China Development Lab の Emerging Technology Institute に勤務するソフトウェア・エンジニアです。彼は 2008年に IBM に入社しました。プログラム分析、バイトコード・インスツルメンテーション、Java 並行プログラムで経験を積んだ彼は、現在、Java 並列ソフトウェアの静的/ランタイム分析ツールに取り組んでいます。彼は、中国・北京の Peking University でソフトウェア・エンジニアリングの修士号を取得しました。

Wei Liu は、IBM China Development Lab の Emerging Technology Institute に勤務するソフトウェア・エンジニアです。北京大学でソフトウェア・エンジニアリングの修士号を取得した彼は、2010年に IBM に入社し、Eclipse RCP および RAP、Java 並行性プログラミング、および動的プログラム分析で経験を積んでいます。

