Top > MyPage
 

BlazeDS事始Ver.1.3.1

はじめに

クライアント側のFlexからサーバー側のjavaオブジェクトを利用するための機構BlazeDSを使ってみたので、どのようにしたかを示す。

BlazeDSをTomcatに導入

BlazeDSをダウンロード

Adobe Open Source BlazeDSにアクセスします。

「Download BlazeDS now」とかかれたリンクがあるので、それをクリックして先に進みます。

topページ

Release BuildsとNightly Buildsの2種類がありますが、Release Buildsのほうをダウンロードするため、「Download the latest BlazeDS Release builds 」とかかれたリンクをクリックして先に進みます。

ダウンロードページ

サンプル導入済みのTOMCATが同梱されているTurnkeyパッケージをダウンロードするため、「Download the BlazeDS turnkey」をクリックします。(これを書いている時点ではblazeds_turnkey_3-0-0-544.zipが最新でした)

ダウンロードページ2

ダウンロードした後

ダウンロードしたファイルを展開すると、下の画像のようなファイルとフォルダが出てきます。この画像はCドライブ直下にblazedsというフォルダを作って展開した例です。展開されたフォルダのひとつにtomcatというものがあります。これはサンプルアプリケーションが配置されているtomcat6.0ですので、これを起動すれば、BlazeDSを使用したアプリケーションのサンプルを確認することができるようです。(このtomcat6.0に用意されているサンプルはshibataは未確認)

展開例

shibataの環境ではすでにTomcat5.5があったので、そちらにBlazeDSを導入してサンプルを動かしてみることにしました。以下のようにしたところサンプルを動作させることができました。以下、ダウンロードしたアーカイブの中身を上の画像と同じようにC:\blazedsに展開、tomcatのルートディレクトリはC:\Program Files\Tomcat 5.5として進めます。

展開されたファイルにC:\blazeds\resources\security\tomcatにflex-tomcat-common.jarとflex-tomcat-server.jarというものがあるはずです。

jar

flex-tomcat-common.jarをtomocatのcommon/libにコピーします。flex-tomcat-server.jarをserver/libにコピーします。(tomcat5.5ではこのような場所にありますが、6.0ではディレクトリ構造が違うようなので要注意です)コピーした後は、トムキャットを起動、あるいは再起動します。

jarコピー先
jarコピー先

C:\blazedsにblazeds.war、ds-console.war、samples.warの3つのwarファイルがあるはずです。これらをtomcatにデプロイします。blazeds.warが本体、ds-console.warが管理者用コンソール、samples.warがサンプルアプリケーションです。

以上で導入完了です。sampleアプリケーションの動作確認を行う前にまず実行すべきプログラムがあります。コマンドプロンプトを開いて、バッチファイルC:\blazeds\sampledb\startdb.batを実行してください。C:\blazeds\sampledbをカレントディレクトリにしてからstartdb.batを実行です。これで、サンプルアプリケーションの動作を見ることができるようになります。

sampleDBバッチ?

ブラウザでsamplesを開くといろいろなサンプルを確認することができます。(http://localhost:8080/samples/のような感じのurlになるはずです)

sampleトップ

サーバサイドのjavaオブジェクトと連携するFlexアプリケーション

端的にいうと、デプロイしたblazeDS(これがリモートオブジェクトデータサービスを提供するサーバということになる)のWEB-INF/classesにjavaクラスを置いてWEB-INF\flex\remoting-config.xmlにそのクラスを定義すると、リモートオブジェクトとしてクライアント側からそのクラスのメソッドを使用することができるようになります。その定義は以下のような感じで記述します。

    <destination id="myRO">
        <properties>
            <source>MyBlazeRO.MYRO</source>
            <scope>application</scope>
        </properties>
    </destination>

上記のように定義されたjavaclassをリモートオブジェクトとしてクライアント側から使うためにはクライアント側のソースファイルで次のように宣言します。

<mx:RemoteObject id="ro" destination="myRO"/>

このように宣言することでBlazeDS側でmyROとして宣言していたオブジェクトをクライアント側でroというオブジェクトとして使用することができます。クライアントがAirである場合はLiveCycleデータサーバ(この場合はBlazeDSの動いているTomcat)のurlを設定してやる必要があるようです。

Flex Builder3をもちいたBlazeDSと連携するFlexアプリケーションの作成例を図示したpptを次の場所からダウンロードすることができます。この例を参考にやってみました。

[PPT]Flex Builder リモートオブジェクトの設定メモ

[PPT]Flex Builder リモートオブジェクトの設定メモ(ミラーリング)

このpptの例に沿う形で作業を進めて「�EMXMLファイルを編集」まで終わらせたらFlexBuilderのメニューから「リリースビルドの書き出し」を行います。

FlexBuilderメニュー

そうすると、ローカルで稼動しているblazeds(shibataの場合はC:\Program Files\Tomcat 5.5\webapps\blazeds)の下に作成したFlexアプリケーションが配置されます。アプリケーションのプロジェクト名がFlexTestだったとすればC:\Program Files\Tomcat 5.5\webapps\blazeds\FlexTest以下に配置され、urlはhttp://localhost:8080/blazeds/FlexTest/FlexTest.htmlとなるでしょう。

今後の課題

上の例では、javaクラスはblazeds以下に配置して、remoting-config.xmlを書き換えました。ですが、サンプルプログラムはsamples以下にjavaオブジェクトがあり、remoting-config.xmlもそちらにあります。Flexの各サンプルもsamples以下にあります。

blazeds以下にできたFlexアプリケーションを他のアプリケーションのフォルダにコピーしても問題なく動作しましたが、javaオブジェクトをblazeds以外の場所に置く方法がまだわかっていません。javaオブジェクトとremoting-config.xmlもサンプルプログラムと同じ配置になるようにしても駄目でした。javaオブジェクトもFlexも同じアプリケーションのフォルダに配置する方法を調べる必要があります。また、javaとactionscriptの型の相関を調べて、正しくデータが渡るようにする必要があります。

既存のwebアプリケーションにBlazeDSを導入

Adobe BlazeDSを自分のWebアプリケーションに組み込む設定

という記事があったので、それを参考にしてすでにlocalhostにあるwebアプリケーションにBlazeDSを組み込んでみました。

まず、次の四つのjarファイルをWEB-INF/libにコピーします。

  • backport-util-concurrent.jar
  • flex-messaging-common.jar
  • flex-messaging-core.jar
  • flex-messaging-remoting.jar

次にweb.xmlにlistener、servlet、servlet-mappingの設定を以下のように書き足します。

  <listener>
    <listener-class>flex.messaging.HttpFlexSession</listener-class>
  </listener>

  <servlet>
    <servlet-name>MessageBrokerServlet</servlet-name>
    <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
    <init-param>
      <param-name>services.configuration.file</param-name>
      <param-value>/WEB-INF/flex/services-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>MessageBrokerServlet</servlet-name>
    <url-pattern>/messagebroker/*</url-pattern>
  </servlet-mapping>
  

次にblazeds.warを展開したら出てくるblazeds/WEB-INF/flex以下のxmlを、BlazeDSを組み込もうとしているアプリケーションのWEB-INF/flexにコピーします。おそらく、次の4つがあるとおもわれます。

  • services-config.xml(web.xmlのservletで設定ファイルとして指定している)
  • remoting-config.xml
  • proxy-config.xml
  • messaging-config.xml

参考にしたページではservices-config.xmlしか使いませんでしたが、remoting-config.xmlを使うようになっているので、そのまま使ってみることにします。まず、remoting-config.xmlのserviceの要素として次のような定義を設定します。これはFlexからリモートオブジェクトとして使うjavaクラスです。リモートオブジェクトとして使いたくクラスをここに書いてください。複数ある場合は複数かいてください。

    <destination id="myRO">
        <properties>
            <source>MyBlazeRO.MYRO</source>
            <scope>application</scope>
        </properties>
    </destination>

次に、services-config.xmlから不要な設定を削ります。次のような感じになると思います。参考にしたページのものと比べてみてください。servicesの要素が違います。

<?xml version="1.0" encoding="UTF-8"?>
<services-config>

    <services>
        <service-include file-path="remoting-config.xml" />
    </services>
    <channels>
<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
<endpoint \
    url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf" \
    class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>

</services-config>

次にリモートオブジェクトとして使いたいjavaクラスをWEB-INF/classes以下にコピーしてください。これで、サーバー側の設定は完了です。

次はFlexアプリケーションで上で設置したオブジェクトを使うようにします。[PPT]Flex Builder リモートオブジェクトの設定メモの例とほぼ同じですが、以下の部分を変更します。

参考にしたpptでは「J2EEサーバーを設定」の画面で、tomcatにデプロイしたblazedsの場所を指定しています。今回はBlazeDSを組み込むアプリケーションのディレクトリやurlを指定してください。

その後、プロジェクトのプロパティーで設定を変更する必要があります。デフォルトだと、サーバーのSDKを使うということになっていると思われますが、blazedsのディレクトリ以外を指定していた場合、SDKが見つからずエラーになります。ですので、次の画像のようにデフォルト(特に変更していなければFlexBuilder同梱のものになっているはず)に変更してください。

FlexBuilderプロパティ、コンパイラメニュー

次にmxmlで記述したソースファイルを書き換えます。リモートオブジェクトを指定している次のようなタグにendpoint属性を追加します。

<mx:RemoteObject id="ro" destination="myRO"/>

こんな感じです

<mx:RemoteObject id="ro" destination="myRO" \
    endpoint="http://localhost:8080/html/messagebroker/amf"/>

あとは、リリースビルドの書き出しを行えば、tomcatのウェブアプリケーションのディレクトリに書き出されるので、トムキャットを起動して、ブラウザで確認することができます。本番用のファイルを書き出す場合はendopointを書き直してビルドすることになるでしょう。

リモートオブジェクトの使い方

簡単な使い方としては、特定のイベントが発生(ボタンをクリックしたり、コンボボックスから選択したり)したときにリモートオブジェクトのメソッドを呼び出して、その返り値をデータグリッドなどにバインドしておくという方法があります。

例えば、前の例にあるroというidを割り振られたjavaオブジェクトにgetStringというStringを返すメソッドがあったとします。あるボタンを押したら、そのメソッドが呼ばれるようにしたい場合、mxmlにつぎのようにかきます。

<mx:Button label="call getString" click="{ro.getString()}"/>

このように書くと、画面上に「call getString」とかかれたボタンが表示され、これを押すとサーバーサイドのjavaオブジェクトのgetStringメソッドが実行されます。

そして、返り値をバインドしておいて表示したい場合は次のようにします。

<mx:Label text="{ro.getString.lastResult}" id="label1"/>

Labelのtextに{ro.getString.lastResult}とバインドされています。getStringの返り値がかえってきたとき(resultイベントが発生したとき)この部分にgetStringメソッドから返された文字列が表示されます。返り値を直接バインドしたいときはこのようにlastResultをつかいます。

 

actionscriptからリモートオブジェクトを呼び出したいときはこのようにします。

        <![CDATA[
            import mx.controls.Alert;
            import mx.rpc.remoting.mxml.RemoteObject;
            import mx.rpc.events.ResultEvent;
            import mx.rpc.events.FaultEvent;

            [Bindable]
            public var remoteObj:RemoteObject;

            public function useRemoteObject():void {
                remoteObj = new RemoteObject("myRO");
remoteObj.getList.addEventListener("result", getStringResultHandler);
                remoteObj.addEventListener("fault", faultHandler);
                remoteObj.getSting();
            }

public function getStringResultHandler(event:ResultEvent):void {
                 // Do something
                label1.text = String(event.result);
            }

            public function faultHandler (event:FaultEvent):void {
             // Deal with event.fault.faultString, etc.
                Alert.show(event.fault.faultString, 'Error');
            }
        ]]>

上の例のようなスクリプトを記述したあと、ボタンを押したときに実行されるメソッドをuseRemoteObjectファンクションに変更します。そしてLabelのtextにバインドしている部分を消します。

<mx:Label id="label1"/>

すると、ボタンが押されたときにfunction useRemoteObject()が呼び出されます。useRemoteObjectではサービスを宣言し(同時に宛先を設定)、result および fault イベントリスナーを設定して、サービスのgetStingを呼び出しています。resultイベントが発生したときはgetStringResultHandlerが実行され、label1.textに文字列がセットされるので、このコンポーネントに文字列が表示されます。faultイベントが発生した場合はAlertが表示されるでしょう。なお、上の例ではリモートオブジェクトの変数名にremoteObjを使っていますが、これがすでにidに使用されている場合は使えない点に注意してください。例えば、roを使おうとするとエラーになります。

actionscriptで宣言しているremoteObjはmxmlのほうからも参照できますので、

<mx:Label text="{remoteObj.getString.lastResult}" id="label1"/>

と、書いていても同じように表示されます。

その反対にmxml側で宣言したリモートオブジェクトをactionscriptから参照することもできます。

            public function useRO():void {
ro.getPCList.addEventListener("result", getPCListResultHandler);
                ro.getString();
                ro.getPCList();
            }
public function getPCListResultHandler(event:ResultEvent):void {
                 // Do something
                dg2.dataProvider = event.result;
            }

ファンクションuseROが実行されると、mxml側で宣言されたリモートオブジェクトroにイベントリスナーを設定して、メソッドgetPCListを実行してresultイベントが発生したらファンクションgetPCListResultHandlerが実行されるよう設定されます。そのあと、サーバーサイドのgetString、getPCListの二つのメソッドが呼びだされます。ファンクションgetPCListResultHandlerではdg2というidを持つコンポーネント(このときはDataGrid)のdataProviderにgetPCListの返り値をセットしています。このようにすると、dg2のdataProviderにro.getPCList.lastResultをバインドした場合と同様に表示されます。

ところで、上の例ではアクションスクリプトでリモートオブジェクトを宣言するためにをimportしています。ですが、Adobe公式のヘルプにあるサンプルを見るとをimportしています。はじめ、公式のサンプルのとおりにやってみたのですが、コンパイルしようとするとエラーが発生しました。調べているうちにというのもあることを知り、こちらをimportしたらうまくいくようになりました。

はを拡張したものらしいので、こちらを使っていれば問題ないと思われます。

シリアルポートを使った通信をlinux上でやろうとしたときに詰まったこと

BlazeDS を使うときに注意すべき点

Tomcat5.5とJDK1.5の環境でmessageBrokerServletの初期化でjavax.xml.xpath.XPathFactoryConfigurationExceptionが発生して失敗することがる。

Xalan(2.7.1?) Xerces(2.9?) が競合するとか ※詳細失念

柴田がfedora9で試したときは以下の二つをダウンロードして中に含まれていたjarファイルをCATALINA_HOME/common/libにコピーしたところ問題なく動作した。

  • Xalan-j_2_7_0
  • Xerces-J-bin.2.9.1

両方に共通するファイルがあるので、柴田は先にXalanの方をコピーして、次にXercesの方をコピーした。同名のファイルはXercesの方で上書きした

RXTXインストール

RXTX公式からzipファイルをダウンロードします。20080808現在での最新がrxtx-2.1-7-bins-r2.zipです

zipを展開すると中にはjarファイルがひとつと、OSごとのドライバファイルがあります。

RXTXcomm.jarはサーバー上のアプリケーションのWEB-INF/libにおいてください

ドライバファイルはlinux(32bit版)の場合は、zipの内容物の以下の二つをJAVA_HOME/jre/lib/i386にコピーしてください

  • Linux/i686-unknown-linux-gnu/librxtxParallel.so
  • Linux/i686-unknown-linux-gnu/librxtxSerial.so

これでRXTXが使えるようになります。

シリアルポートを使った通信でひっかかったこと

  • port名がwindowsとlinuxでちがう。WindowsではCOM1のポートが、Linuxでは/dev/ttyS0
  • ロックファイルを書き出す権限が無いとエラーになる柴田が試したときは/var/lockに書き込み属性を加えたらオッケーになりました
  • どういうわけか、suでないとポートを見つけることができなかった。(一覧表示させようとするが、普通のユーザーだと何もかえってこない。そのデバイスを使うう権限がないから?)tomcatのユーザーがrootであれば問題なくtomcatのアプリケーションからシリアルポートを使うことができた