同じソースで動くS2RMIとS2Axis

現在、同じソースで、S2RMIS2Axisを切り替えて動かすサンプルを作成中。
論理的にはできることは分かっていたけど、実際に試してはいませんでした。


ごくごく簡単な例ですが、以下のような感じで実現できます。

サーバ側

  • 公開するサービス
public interface HelloService {
    public String say();
}

public class HelloServiceImpl implements HelloService {
    public String say() {
        return "Hello";
    }
}
<components xmlns:xi="http://www.w3.org/2001/XInclude">  
  <component
    name="RMIAdapptor"
    class="org.seasar.remoting.rmi.adaptor.impl.RMIAdaptorImpl">
    <property name="invokerName">"componentInvoker"</property>
  </component>
  
  <component name="componentInvoker"
    class="org.seasar.extension.component.impl.ComponentInvokerImpl">
  </component>
  
  <component
    class="org.seasar.remoting.rmi.filter.impl.RMIExternalContextFilter">
  </component>
  
  <component class="org.seasar.remoting.rmi.deployer.impl.RMIAdaptorDeployerImpl">
    <property name="registryPort">1108</property>
    <property name="servicePort">1109</property>
    <initMethod name="deploy"/>
    <destroyMethod name="undeploy"/>
  </component>
  
  <component
    name="helloService"
    class="examples.communication.service.impl.HelloServiceImpl">
  </component>
</components>
<components xmlns:xi="http://www.w3.org/2001/XInclude">
  <component
    name="helloService"
    class="examples.communication.service.impl.HelloServiceImpl">
    <meta name="axis-service"/>
  </component>
</components>
  • app.dicon
<components xmlns:xi="http://www.w3.org/2001/XInclude">
  <include path="aop.dicon"/>
  <include path="s2-axis.dicon"/>
  <include path="s2rmi-examples.dicon"/>
  <include path="s2axis-examples.dicon"/>
</components>

クライアント側

  • サービスを呼び出すクライアント
    • mainの部分で、S2Containerを初期化する際に指定するdiconを切り替えることで、S2RMIS2Axisを切り替えます。
public class HelloClient {

    private HelloService service;

    public void execute() {
        System.out.println(this.service.say());
    }

    public static void main(String[] args) throws Exception {
        S2Container container;

        // S2Containerの初期化

        S2AxisHelloClient client = new HelloClient();
        client.service = (HelloService) container.getComponent(HelloService.class);
        client.execute();
    }

}
<components xmlns:xi="http://www.w3.org/2001/XInclude">
  <component
    name="remoting"
    class="org.seasar.remoting.common.interceptor.RemotingInterceptor">
  </component>
  
  <component
    class="org.seasar.remoting.rmi.connector.impl.RMIConnectorImpl">
    <property name="baseURLAsString">"rmi://localhost:1108/"</property>
    <initMethod name="lookup"/>
  </component>
  
  <component
    name="helloService"
    class="examples.communication.service.HelloService">
    <aspect>remoting</aspect>
  </component>
</components>
<components xmlns:xi="http://www.w3.org/2001/XInclude">
  <component
    name="remoting"
    class="org.seasar.remoting.common.interceptor.RemotingInterceptor">
  </component>

  <component
    class="org.seasar.remoting.axis.connector.AxisConnector">
    <property name="baseURL">"http://localhost:8080/s2-communication-server/services/"</property>
  </component>
  
  <component
    class="org.apache.axis.client.Service"
    autoBinding="none">
  </component>
  
  <component
    name="helloService"
    class="examples.communication.service.HelloService">
    <aspect>remoting</aspect>
  </component>
</components>

改めて実感

RMISOAP実装を経験したことが無い人にとっては、何がうれしいか分からないかも知れませんが、通信方式がdiconの設定だけで切り替えられるのは、自分の中ではイノベーションだったことを改めて実感しました。


以前ならば、

  • RMI
    • サーバ側ではLookupサービスへの登録処理を実装して、クライアントではLookupから取得する処理を実装して、rmicでコンパイルして、rmiレジストリのプロセスを立ち上げて、アプリケーションのプロセスを立ち上げて・・・
  • SOAP(Axis)
    • WSDDファイルを書いて、サービスのインタフェースを自動生成して、サーバ側ではAPサーバにデプロイして・・・

と、実装も実行も大変でした。
私の場合、アプリケーションを実装する上で、気にしたくないところにばっかり時間がかかっていました。


上記の例は、必要となるファイルがある程度多いため、一見面倒に見えるかもしれませんが、一度定義してしまえば、ほとんど変更する必要はありません(今回は分かりやすいように書いていますが、AutoRegisterやSMARTdeployを使えば、より簡略化できます)。

実行の際も、デプロイなどの作業は不要です。


複雑であった分散処理をいかに簡単にするか、それがS2Remotingファミリで実現したいところですね。