Tuscany で JSONRPC とスクリプトのサンプル作成

Tuscany SCA 0.99 を使って JSONRPC の簡単なサンプルを作成する。
Tuscany SCA のサンプル helloworld-jsonrpc を参考に、サービスの実装を Groovy スクリプトにしてみた。

手順は以下の通り。

  1. Java でサービスインターフェース作成
  2. Groovy でサービスインターフェースの実装作成
  3. SCAコンポーネントの定義ファイル(.composite)作成
  4. 配備用のファイル(sca-contribution.xml)作成
  5. HTML 作成
  6. web.xml 作成
  7. war ファイル作成
  8. Tomcat に配備して実行

Java でサービスインターフェース作成

サービスインターフェースを普通の Java インターフェースとして作成。

SimpleService.java
package simple;

public interface SimpleService {
    int calculate(int a, int b);
}

Groovy でサービスインターフェースの実装作成

サービスインターフェースのメソッドを Groovy スクリプトで実装。

なお、スクリプトファイルは .war ファイル内の WEB-INF/classes 内に配置する。

simpleService.groovy
def calculate(a, b) {
    return a + b
}

SCAコンポーネントの定義ファイル(.composite)作成

.composite ファイルで、JSONRPC で公開するサービスとコンポーネントの定義を記述する。

binding.jsonrpc 要素で JSONRPC での公開を指定し、promote 属性でサービスの実装先コンポーネントを指定。

なお、.composite ファイルは、.war ファイル内の WEB-INF/classes に配置する

simple.composite
<?xml version="1.0" encoding="UTF-8"?>

<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
           xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
           targetNamespace="http://simple"
           xmlns:simple="http://simple"
           name="simplejson">

    <service name="SimpleService" promote="SimpleServiceScriptComponent">
        <interface.java interface="simple.SimpleService"/>
        <tuscany:binding.jsonrpc/>
    </service>

    <component name="SimpleServiceScriptComponent">
        <tuscany:implementation.script script="simple/simpleService.groovy"/>
    </component>

</composite>

配備用のファイル(sca-contribution.xml)作成

deployable 要素の composite 属性に .composite ファイルの composite 要素の name 属性の値を指定。

なお、sca-contribution.xml は、.war ファイル内の META-INF ディレクトリに配置する。

sca-contribution.xml
<?xml version="1.0" encoding="UTF-8"?>

<contribution xmlns="http://www.osoa.org/xmlns/sca/1.0"
              targetNamespace="http://simple"
              xmlns:simple="http://simple">

    <deployable composite="simple:simplejson"/>

</contribution>

HTML 作成

サーブレットエンジン側で自動的に生成される SCA/SCADomain/scaDomain.js を使って、サービスの呼び出し処理を JavaScript で記述。

simple.html
<html>
<head>
<title>Tuscany Simple</TITLE>
<script type="text/javascript" src="SCA/SCADomain/scaDomain.js"></script>
<script type="text/javascript">

    function calculate() {
        var a = document.getElementById("a").value;
        var b = document.getElementById("b").value;

        SimpleService.calculate(a, b, handleResponse);
    }

    function handleResponse(result) {
        document.getElementById('c').value = result;
    }

</script>
</head>
<body onload="calculate()">

    <h1>JSONRPC Script Sample</h1>

    <input type="text" id="a" size="30" value="0" />
    +
    <input type="text" id="b" size="30" value="0" />
    =
    <input type="text" id="c" size="30" value="" />
    <input type="button" value="計算" onclick="calculate()" />

</body>
</html>

Tomcat 配備後の最初の calculate 実行時には値が戻って来ないようなので、onload 時にとりあえず 1度実行しておくようにした。

web.xml 作成

Tuscany で Web アプリケーションを作成するためのお決まりの定義を記述する。

web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC 
    "-//Sun Microsystems, Inc.//DTD WebApplication 2.3//EN" 
    "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
    <display-name>Test jsonrpc and script</display-name>

    <listener>
        <listener-class>org.apache.tuscany.sca.host.webapp.TuscanyContextListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>TuscanyServlet</servlet-name>
        <servlet-class>org.apache.tuscany.sca.host.webapp.TuscanyServlet</servlet-class>
    </servlet>
 
    <servlet-mapping>
        <servlet-name>TuscanyServlet</servlet-name>
        <url-pattern>/SCA/*</url-pattern>
    </servlet-mapping>

    <welcome-file-list id="WelcomeFileList">
        <welcome-file>simple.html</welcome-file>
    </welcome-file-list>  
</web-app>

war ファイル作成

以下のような build.xml ファイルを作成、Apache Ant を使って war ファイルを作成する。

build.xml
<project name="Test jsonrpc and script" default="package">
    <property environment="env" />

    <target name="init">
        <mkdir dir="target/classes"/>
    </target>

    <target name="compile" depends="init">
        <javac srcdir="src/main/java" 
               destdir="target/classes"
               debug="on"
               source="1.5"
               target="1.5">
            <classpath>
                <pathelement location="${env.TUSCANY_HOME}/lib/tuscany-sca-manifest.jar"/>
            </classpath>
        </javac> 
        <copy todir="target/classes">
            <fileset dir="src/main/resources"/>
        </copy>
    </target>

    <target name="package" depends="compile">
        <war destfile="target/simple-jsonrpc.war" 
             webxml="src/main/webapp/WEB-INF/web.xml">
            <fileset dir="src/main/webapp"/>
            <zipfileset dir="${env.TUSCANY_HOME}/modules" prefix="WEB-INF/lib">
                <include name="sca-api-0.99-incubating.jar"/>
                <include name="tuscany-assembly-0.99-incubating.jar"/>
                <include name="tuscany-assembly-xml-0.99-incubating.jar"/>
                <include name="tuscany-binding-jsonrpc-0.99-incubating.jar"/>
                <include name="tuscany-binding-sca-0.99-incubating.jar"/>
                <include name="tuscany-binding-sca-xml-0.99-incubating.jar"/>
                <include name="tuscany-contribution-0.99-incubating.jar"/>
                <include name="tuscany-contribution-impl-0.99-incubating.jar"/>
                <include name="tuscany-contribution-java-0.99-incubating.jar"/>
                <include name="tuscany-contribution-namespace-0.99-incubating.jar"/>
                <include name="tuscany-core-0.99-incubating.jar"/>
                <include name="tuscany-core-databinding-0.99-incubating.jar"/>
                <include name="tuscany-core-spi-0.99-incubating.jar"/>
                <include name="tuscany-databinding-0.99-incubating.jar"/>
                <include name="tuscany-distributed-0.99-incubating.jar"/>
                <include name="tuscany-extension-helper-0.99-incubating.jar"/>
                <include name="tuscany-host-embedded-0.99-incubating.jar"/>
                <include name="tuscany-host-http-0.99-incubating.jar"/>
                <include name="tuscany-host-webapp-0.99-incubating.jar"/>
                <include name="tuscany-implementation-java-0.99-incubating.jar"/>
                <include name="tuscany-implementation-java-runtime-0.99-incubating.jar"/>
                <include name="tuscany-implementation-java-xml-0.99-incubating.jar"/>
                <include name="tuscany-interface-0.99-incubating.jar"/>
                <include name="tuscany-interface-java-0.99-incubating.jar"/>
                <include name="tuscany-interface-java-xml-0.99-incubating.jar"/>
                <include name="tuscany-policy-0.99-incubating.jar"/>
                <include name="tuscany-policy-xml-0.99-incubating.jar"/>
                <!-- Groovy スクリプト実行用の jar ファイル  -->
                <include name="tuscany-implementation-script-0.99-incubating.jar"/>
            </zipfileset>
            <lib dir="${env.TUSCANY_HOME}/lib">
                <include name="cglib-nodep-2.1_3.jar"/>
                <include name="geronimo-commonj_1.1_spec-1.0.jar"/>
                <include name="json-rpc-1.0.jar"/>
                <include name="stax-api-1.0.1.jar"/>
                <include name="wstx-asl-3.2.1.jar"/>
                <!-- Groovy スクリプト実行用の jar ファイル  -->
                <include name="bsf-all-3.0-beta1.jar"/>
                <include name="groovy-all-1.0.jar"/>
            </lib>
            <classes dir="target/classes"/>
        </war>
    </target>

    <target name="clean">
        <delete quiet="true" includeemptydirs="true">
            <fileset dir="target"/>
        </delete>
    </target>
</project>

Tuscany の helloworld-jsonrpc サンプルの build.xml を元に、Groovy スクリプトを処理するための jar ファイル(tuscany-implementation-script-0.99-incubating.jar, bsf-all-3.0-beta1.jar, groovy-all-1.0.jar)用の設定を加えて編集。war ファイルにこれらのファイルが含まれていないと Groovy スクリプトが正常に実行されない模様。

Tomcat に配備して実行

作成した war ファイルを J2SE 5 で実行した Tomcat の webapps ディレクトリに配置し、Web ブラウザで実行を確認。(Tomcat 5.5.25 上で動作確認した)

http://localhost:8080/simple-jsonrpc/

なお、war ファイル内の設定に問題なければ Tomcat に配置した際に以下のようなログが出力される。

情報: Webアプリケーションアーカイブ simple-jsonrpc.war を配備します
org.apache.tuscany.sca.host.webapp.WebAppServletHost addServletMapping
情報: addServletMapping: /SimpleService
org.apache.tuscany.sca.host.webapp.WebAppServletHost addServletMapping
情報: addServletMapping: /SCADomain/scaDomain.js