レベル: 中級 Dan Becker, Software Developer, IBM Japan, Software Group
2009年 03月 24日 サービス・コンポーネント・アーキテクチャー (SCA) とは、ベースとなるコンピューター・サービスを抽象化することによって、システムの柔軟性を高め、さまざまに異なる技術で実装されたサブシステムを組み込めるようにする新しい技術のことです。SCA はアクセス技術、実装、そしてプロトコルに関する多くの詳細をミドルウェア層に移し、ビジネス・ロジックから切り離します。しかし、このような抽象化によって犠牲を強いられる開発者もなかにはいます。ビジネス・アプリケーションを理解し、デバッグするのが難しくなるためです。この記事を読んで、さまざまなプロトコル・バインディングと実装タイプで呼び出しが行われるなかで、コンポーネントがどのように呼び出されるかを学んでください。この記事ではオープンソースの Apache Tuscany SCA ランタイムを使用した例を用いて、SCA に内在する複雑さについて説明します。
はじめに
ビジネスの世界には 2 つの重要な駆動力があります。それは、変化と多様性です。皆さんが現在適用しているビジネス・ソリューションが何であれ、いずれは変更し、新しい機能を加え、サービスを改善するために部分的に更新し、あるいはサプライヤーの気まぐれに適応させる必要があることはご存知のはずです。さらに、変化と多様性という 2 つの駆動力が、ビジネス・ソリューションを素早く市場に出すよう容赦なく圧力をかけてきます。ビジネスが大規模なプロジェクトを端々まで設計し、すべてのサブシステムを管理できた時代はもう過去の話です。
SCA は、変化と多様性に対応する新しい技術です。ベースとなる実装技術の大部分を抽象化することにより、SCA はシステムがより柔軟かつ素早く変化に適応するとともに、さまざまに異なる技術で実装されたサブシステムを組み込めるようにします。その方法は、アクセス技術、実装、そしてプロトコルに関する詳細の大部分をミドルウェア層に移し、ビジネス・ロジックから切り離すというものです。
一部の技術設計者や開発者はすでに、SCA のサンプル実装、あるいは既存のサービスの更新に向けて第一歩を踏み出しましたが、技術を使用する側が成長していくにつて、さまざまな疑問があがってくるものです。SCA の場合、以下の疑問があります。
- SCA コンポーネント間では、具体的にどのような方法で対話するのか
- クライアント・プログラムが SCA アプリケーションと対話するときに、SCA ランタイムはその SCA アプリケーションの実装でどのようにしてメソッドを呼び出すのか
- SCA アプリケーションに問題が発生した場合、ランタイム呼び出しスタックに示されるさまざまなクラスを説明できる人がいるのか
この記事では、これらの疑問に対する答えを学びます。
SCA ランタイム
この記事で例として用いるのは、Apache Tuscany SCA ランタイム環境です。これを選んだ理由には、以下が挙げられます。
- Apache Tuscany はオープンソースの SCA 実装なので、無料でダウンロードすることができます。この記事の内容を追っていくには、Tuscany と Eclipse 開発プラットフォームをインストールしてください。
- Tuscany は特定のベンダーにも、特定のプラットフォームにも依存しません。スタンドアロンで実行可能な Tuscany は、複数のベンダーのサーバー (Tomcat、JBoss、Geronimo、IBM® WebSphere®、WebLogic) と連動することも、複数のプラットフォーム (Microsoft® Windows®、Linux®、Mac OS) で実行することもできます。
- Tuscany は、この記事で取り上げるプロトコル・バインディングと実装の多くを使用します。SCA ではベースにある実装の複雑さを開発者から隠し、開発者が変化への対応やさまざまな種類のサブシステムの統合に専念できるようにしますが、その仕組みを説明するには、Tuscany は理想的なプラットフォームです。
SCA の基本概念
基本的な SCA 用語をよく知らないという方のために、このセクションでは、多くの SCA 実装で共通して使用されていて、最近のオープン SOA 仕様で承認された用語を概説しておきます。
SCA アプリケーションは「アセンブリー (assembly)」によってモデル化され、SCA アセンブリー内には一連の成果物と、これらの成果物を結び付ける接続があります。アセンブリーは「コンポジット・ファイル (composite file)」に保管されます。コンポジット・ファイルは多くの場合、SCA の各部分と、これらの部分を結び付ける接続が含まれる XML ファイルとして記述されます。コンポジット・ファイルは、Tuscany などの SCA ランタイムによってロードされ、実行可能な状態になります。図 1 に、アセンブリーの一例を示します。
図 1. 典型的な SCA アセンブリー
基本的な SCA 成果物である「コンポーネント (compopnent)」は、ビジネス・アプリケーションのビルディング・ブロックです。コンポーネントは基本的なビジネス機能 (例えば株価情報サービスや計算機サービスなど) を提供します。コンポーネントにはビジネス・サービスの動作方法を制御するプロパティーを設定することができ、これらのプロパティーによって、コンポーネントの構成を指定します。SCA コンポーネントは、いくつもの技術を使用して実装することが可能です。SCA 仕様では基本的な実装タイプのセット (Java™ 技術、BPEL、J2EE、および Spring) を定義し、他の SCA 構成を繰り返し作成できるようにしています。Tuscany ではこの基本セットに加え、スクリプト言語 (Jscript、Groovy、PGP、Python、Ruby) や OSGi などが含まれるセットを追加しています。これらの実装タイプは、異種のサブシステムを組み込んで既存のコードを再利用することを目的としています。
SCA コンポーネントの機能は、他のコンポーネントにサービスとして提供され、SCA コンポーネントは「参照 (reference)」という手段でサービスを利用します。サービスと参照は連結されて可視化され、プロモーションによって外部に公開されます。それぞれのサービスまたは参照には、ビジネス・インターフェースを「メソッド (method)」のセットとして記述するインターフェースがあります。各メソッドには名前、多数のパラメーター、戻り値があります。SCA はこれらのインターフェースを Java 言語インターフェース、あるいは WSDL (Web Services Description Language) ファイルを使用して定義します。各サービスまたは参照には、アクセス「バインディング (binding)」によってアクセスします。アクセス・バインディングは、サービスまたは参照へのアクセスに使用できるプロトコルを定義します。現在 SCA 仕様でよく使用されるバインディング技術の基本セットとして言及しているのは、HTTP、JMS、Web サービス、および SCA などです。SCA は、2 つのコンポーネントが同じ Java 仮想マシンで実行されていて、バインディングが指定されていない場合によく使用されます。
Tuscany ではこの他に、Web 2.0 スタイルのアプリケーション、Atom、RSS、JSON/RPC などのサポートに役立つバインディング・セットを追加しています。図 2 に示すように、Tuscany ランタイムは各種の技術からプロトコル固有のメッセージを取り、これらのメッセージをビジネス・コンポーネント実装が使用できる形に変換します。ビジネス・コンポーネント実装はデータを処理した後、これを Tuscany SCA ランタイムに戻します。この場合の目的も同じく、既存のアクセス技術を統合し、再利用することによって、ビジネス・コンポーネントの開発者がビジネス機能に専念できるようにすることです。
図 2. SCA ランタイム・スタック
最後に、ビジネス・インターフェースに含まれる各メソッドが呼び出されると、メソッドにパラメーターとして提供されたデータと、呼び出しによって返されたデータが、データ・バインディングを使用して抽象化されます。共通データ型には、Java オブジェクト、XML 文書、SDO (Service Data Object) があります。Tuscany は各種データ型間での変換を自動的に行い、プロバイダーおよびクライアントとの間のデータ・フローを容易に行えるようにします。この記事で焦点とするのはデータ・バインディングではありませんが、この用語の複数の使い方を知っておくことが重要です。
このセクションでは、SCA がビジネス・アプリケーション開発者に提供するさまざまな概念に焦点を当てました。インターフェースは現在、Java 言語または WSDL で指定されます。アクセス・バインディングはいくつものプロトコル (HTTP、JMS、Web サービス、Atom、JSON/RPC) で実装されます。コンポーネントについても、複数の技術 (Java 技術、BPEL、SCA、Spring、J2EE、スクリプト言語、OSGi) で実装することができます。この記事の残りの部分では、サービス呼び出しから実装内でのビジネス・メソッド呼び出しへとつながる根本的な流れを理解できるように、これらの技術がどのように相互作用するかを説明します。
シナリオ
この例では、単純なビジネス・アプリケーションが進化していく様子を追いかけます。シナリオで使用する例のサンプル・コードはダウンロードすることができます (このアプリケーションは例として説明するために、簡潔かつ大幅に単純化されています)。
このビジネス・サービスで唯一の要件となっているのは、2 つの数値を合計することです。この計算機サービスは公開され、クライアントが呼び出せるようになっています。計算機 (Calculator) が接続されているのは、add サービス (AddService) です。このサービスが持つ唯一の関数 add によって、2 つの数値が合計され、その値が返されます (例えば、
double add(double o1, double o2) など)。インターフェースは Java 言語で指定されていて、サービスも同じく Java 言語で実装されているという前提です。図 3 に、この SCA アセンブリーを示します。
図 3. 加算を行う SCA 計算機コンポーネント
上記のアセンブリーでは、1 つの計算機コンポーネントとその実装が指定されていて、このコンポーネントが add サービス・コンポーネントとその実装を参照します。リスト 1 に、このビジネス・アプリケーションに対応する SCA コンポジット・ファイルを記載します。このコンポーネントと他のコンポーネントのソース・コードをダウンロードしてください。
リスト 1. 計算機のコンポジット・ファイル
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:sample="http://sample"
name="Calculator">
<component name="CalculatorServiceComponent">
<implementation.java class="calculator.CalculatorServiceImpl"/>
<reference name="addService" target="AddServiceComponent"/>
</component>
<component name="AddServiceComponent">
<implementation.java class="calculator.AddServiceImpl"/>
</component>
</composite>
|
ここで、顧客の要件が拡大して数値を減算する新しいサービスが必要になったとします。しかし、利用できる Web サービスはインターフェースを WSDL 文書として指定し、Java プログラムとして実装されているサービスです。この Web サービスへのアクセスには、Web サービス・アクセス・バインディングが使用されます。この新しい要件は、1 つの参照と、減算サービスにアクセスするコンポーネントを追加することで、SCA コンポジット・ファイルに容易に追加することができます。
リスト 2. 新規サービスが追加された計算機のコンポジット・ファイル
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:sample="http://sample"
name="Calculator">
<component name="CalculatorServiceComponent">
<implementation.java class="calculator.CalculatorServiceImpl"/>
<reference name="addService" target="AddServiceComponent"/>
<reference name="subtractService" target="SubtractServiceComponent"/>
</component>
<component name="AddServiceComponent">
<implementation.java class="calculator.AddServiceImpl"/>
</component>
<component name="SubtractServiceComponent">
<implementation.java class="calculator.SubtractServiceImpl"/>
<service name="SubtractService">
<interface.wsdl interface="http://calculator#wsdl.interface(SubtractService)" />
<binding.ws uri="http://localhost:8080/SubtractServiceComponent"/>
</service>
</component>
</composite>
|
このビジネス・サンプルの進化を完成させるために、今度は乗算および除算サービスの要件を追加します。これらのサービスは JScript 実装と Groovy 実装として用意されていますが、Tuscany ではこの 2 つのサービスを容易にコンポジット・ファイルに追加することができます。これらのサービスを追加すると、ビジネス・アプリケーションは図 4 のようになります。
図 4. 4 つのサービスを備えた SCA 計算機
アプリケーションの最終的な SCA コンポジット・ファイルでは、JScript コンポーネントと Groovy コンポーネントの追加は、SCA 仕様に対する Tuscany 固有の拡張であることに注意してください。そのため、新しい名前空間属性では、この 2 つのコンポーネントに対応する Tuscany 固有の構文を取り込んでいます。
リスト 3. 4 つのサービスを備えた計算機のコンポジット・ファイル
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:sample="http://sample"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
name="Calculator">
<component name="CalculatorServiceComponent">
<implementation.java class="calculator.CalculatorServiceImpl"/>
<reference name="addService" target="AddServiceComponent"/>
<reference name="subtractService" target="SubtractServiceComponent"/>
<reference name="multiplyService" target="MultiplyServiceComponent" />
<reference name="divideService" target="DivideServiceComponent" />
</component>
<component name="AddServiceComponent">
<implementation.java class="calculator.AddServiceImpl"/>
</component>
<component name="SubtractServiceComponent">
<implementation.java class="calculator.SubtractServiceImpl"/>
<service name="SubtractService">
<interface.wsdl interface="http://calculator#wsdl.interface(SubtractService)"/>
<binding.ws uri="http://localhost:8080/SubtractServiceComponent"/>
</service>
</component>
<component name="MultiplyServiceComponent">
<tuscany:implementation.script script="calculator/MultiplyServiceImpl.js"/>
</component>
<component name="DivideServiceComponent">
<tuscany:implementation.script script="calculator/DivideServiceImpl.groovy"/>
</component>
</composite>
|
このシナリオでは、2 回の要件変更に迅速に対処し、元のビジネス・アプリケーションに 3 つのコンポーネントを追加しました。新しく実装したコンポーネントには、元のコンポーネントとは別の技術でアクセスします。このように、SCA では要件の変更や異種のビジネス要件に対応することができます。
これまで、Tuscany ランタイムがこれらの異なる技術へのアクセスを単純化し、SCA コンポジット・ファイルが技術固有の項目に比較的とらわれないことを説明してきましたが、これらの技術が表面下で呼び出される仕組みについてはまだ説明していません。ここからは、SCA 内部の詳細を探っていきます。
Tuscany 呼び出しのアーキテクチャー概要
SCA は、アクセス技術、実装、そしてプロトコルに関する詳細の大部分をビジネス・ロジックから切り離し、ミドルウェア層に移します。これはビジネス・アプリケーションの開発者にとっては望ましいことですが、ソフトウェア開発者にとってはどうでしょうか。このセクションでは Tuscany フレームワークの内部を探り、ビジネス・コンポーネント実装が呼び出される際の一般的な呼び出し経路を明らかにします。
SCA ビジネス・アプリケーションを実行する際に SCA ランタイム (Tuscany など) が実行する最初のステップは、SCA コンポジット・ファイルをロードして構成することです。SCA ランタイムが各種のコンポジット・ファイル成果物を調べる一方、ファクトリー・メソッドがメモリー内での各種オブジェクトのインスタンス化を支援します。そして次のステップで、コンポーネントを接続するランタイム・ワイヤーをインスタンス化します。この段階で、コンポジット・ファイル内に記述されているバインディングにコンポーネント参照とコンポーネント・サービスのランタイム・ワイヤーが作成されます。
「ランタイム・ワイヤー (runtime wire)」とは一連の呼び出しチェーンのことで、ビジネス・インターフェースのメソッドごとに 1 つの呼び出しチェーン (invocation chain) があります。メッセージ交換オペレーターとして機能するハンドラーが作成され、このハンドラーによってそれぞれのメソッド呼び出しが適切な呼び出しチェーンにルーティングされます。各呼び出しチェーンを構成するのは、一連の「インボーカー (invoker: 呼び出しを行うモジュール)」と「インターセプター (interceptor)」です。インボーカーは、バインディング・プロトコルと実装技術に対して呼び出しロジックを提供します。インターセプターは、データ変換、セキュリティー、トランザクション制御などの追加機能を提供する特殊なインボーカーです。コンポーネント参照の場合は、選択されたバインディングを介したアウトバウンド呼び出しを表すランタイム・ワイヤーが作成され、コンポーネント・サービスの場合は、実装タイプへのインバウンド呼び出しを表すランタイム・ワイヤーが作成されます。コールバック・チェーンをランタイム・ワイヤーに追加して、コンポーネントへの逆コールバックを行うこともできます。
計算機コンポーネントから add コンポーネントにメッセージが渡されるまでに、計算機アプリケーションでは以下の経路で呼び出しが行われます。
- 呼び出しが
InvocationHandler に送られます。この例では、InvocationHandler は Java 技術ベースのハンドラーです。
InvocationHandler が正しい InvocationChain を検索します。この例で検索するのは、add メソッドのチェーンです。
- 各種のインボーカーとインターセプターがメッセージを作成してペイロードを設定し、
TargetInvoker を設定してからメッセージをチェーンに渡します。
TargetInvoker が、ベースとしているプロトコル上でメッセージを起動します。SCA コンポーネントはデータ変換やプロトコル変換を実行しなくてすむように、別の SCA コンポーネントへの参照によって double 型の値を渡します。
- 受信側では、リスナーがベースのプロトコルからメッセージを取得し、そのメッセージを受信側コンポーネントの呼び出しチェーンのいずれかにルーティングします。この場合の SCA コンポーネントも Java 技術で実装されています。ここで検出されるのは、add メソッドに対応するチェーンです。
- 呼び出しチェーンが
add サービスの add メソッドを検出すると、メソッド呼び出しを起動します。するとコンポーネント実装が数値を加算して、その合計を返します。
- 呼び出し側コンポーネントまで、逆の経路が取られます。
この経路を以下に示します。
図 5. ソースからターゲットへの SCA 呼び出し
Tuscany での Java 間呼び出し
SCA アプリケーションの例をデバッガーに組み込み、AddService の add メソッドにブレーク・ポイントを設定すると、呼び出しスタック・トレースはリスト 4 のようになります。先頭にあるのは、計算機サービス実装の呼び出し側です。add メソッドは、サービスの Java プロキシー表現を呼び出します。JDKInvocationHandler がメッセージを適切な呼び出しチェーンにルーティングすると、特殊な PassByValueIntercepter がメッセージを渡す SCABindingInvoker を見つけます。すると SCABindingInvoker がサービス側でミラー・イメージ PassByValueInterceptor を見つけます。メッセージは Java 呼び出しに変換され、これによって add サービス・コンポーネント実装が呼び出されます。
リスト 4. Java 呼び出しスタック
CalculatorServiceImpl.add(double, double) line: 54
$Proxy7.add(double, double) line: not available
JDKInvocationHandler.invoke(Object, Method, Object[]) line: 155
JDKInvocationHandler.invoke(InvocationChain, Object[], RuntimeWire, EndpointReference)
line: 287
PassByValueInterceptor.invoke(Message) line: 112
SCABindingInvoker.invoke(Message) line: 61
PassByValueInterceptor.invoke(Message) line: 112
JavaImplementationInvoker.invoke(Message) line: 132
Method.invoke(Object, Object...) line: not available
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available
NativeMethodAccessorImpl.invoke(Object, Object[]) line: not available
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available
AddServiceImpl.add(double, double) line: 30
|
計算機サービスから add サービスへの add 呼び出しをたった 1 回行うにしては、ずいぶんと長いチェーンに見えますが、ビジネス世界のドメインからベースにある技術ドメインへのこのような抽象化は、あらゆるビジネス・アプリケーションに存在するものです。この種の機能を自分で実装するとしたら、この層を実装して管理するという重荷を背負うことになります。
Apache Tuscany の SCA ランタイムにはこの実装がすでに用意されているため、こうした層の実装や管理などの作業をする必要がありません。Tuscany には上記に示した単純な Java 間の呼び出しのほかにも、さまざまなコンポーネント実装タイプのサービスおよび参照バインディングが豊富に揃っています。技術実装がビジネス・ロジックから切り離されることで、アプリケーションは大幅に単純化されます。
Tuscany での Java と WSDL 間の呼び出し
ここに示す SCA アプリケーションの例では、計算機サービスから減算サービス・メソッドへの一層複雑な呼び出しを行います。どちらのサービスも Java 技術で実装されていますが、この例の場合、減算サービスは WSDL インターフェースで記述されているため、呼び出しは Web サービスのアクセス・バインディングで実行されます。このように、SCA ではさまざまに異なる技術を参照し、そうした技術を利用することができます。
この例では、同じ一般的な呼び出し経路が適用されますが、経路に存在するインターセプターの数は増えることになります。これは、Tuscany ランタイムが Java 技術ベースの呼び出しを、ベースとなるプロトコルの Web サービス・メッセージに変換しなければならないためです。例えば、DataTransformationInterceptor が呼び出されて、double 型の値の Java 表現がネイティブ Web サービスの XML 表現に変換されるといった具合です。ターゲット・コンポーネントに対するソース・コンポーネントの呼び出しは、図 6 に示すようにいくつもの段階で行われます。図 5 と同じ色分けで、呼び出しにおけるそれぞれの段階の役割を表します。
図 6. 中間クラスを使用した SCA 経路
ここでも同じく、この計算機 SCA アプリケーションと Tuscany ランタイムをデバッガーに組み込み、ブレーク・ポイントをサービスの subtract メソッドに設定すると、リスト 5 のような結果になります (このスタックは呼び出しを受信する部分のみを示しています。Web サービスは一般に、HTTP プロトコル層の上部に位置するため、HTTP 層はメッセージ呼び出しをリクエストとして受信し、このリクエストを処理する大元の Web サービス層に転送します)。
呼び出しスタックの最上位層では、メッセージ呼び出しを処理する大元の技術である Web サービス・エンジンが呼び出しを受信します。Apache Tuscany が使用するのは Axis2 Web サービス・エンジンであるため、呼び出しスタックには複数の Axis2 クラスがあります。続いて Tuscany の RuntimeWire というインボーカーがネイティブ・メッセージを受信し、呼び出すべき正しい呼び出しチェーンを見つけます。この呼び出しは、DataTransformationInterceptor を呼び出すことで開始されます。これによって Web サービス表現が Java double に再び変換されます。そして最後に、JavaImplementationInvoker が減算サービスで Java subtract メソッドを見つけて呼び出します。
リスト 5. Web サービス呼び出しスタック
AxisEngine.receive(MessageContext) line: 176
Axis2ServiceInOutSyncMessageReceiver(AbstractMessageReceiver).receive(MessageContext)
line: 100
Axis2ServiceInOutSyncMessageReceiver(AbstractInOutSyncMessageReceiver).
invokeBusinessLogic(MessageContext) line: 42
Axis2ServiceInOutSyncMessageReceiver.invokeBusinessLogic(MessageContext, MessageContext)
line: 70
Axis2ServiceProvider.invokeTarget(Operation, Object[], MessageContext) line: 736
RuntimeWireImpl.invoke(Operation, Message) line: 158
RuntimeWireInvoker.invoke(Operation, Message) line: 98
RuntimeWireInvoker.invoke(RuntimeWire, Operation, Message) line: 104
RuntimeWireInvoker.invoke(InvocationChain, Message, RuntimeWire) line: 129
DataTransformationInterceptor.invoke(Message) line: 78
JavaImplementationInvoker.invoke(Message) line: 132
Method.invoke(Object, Object...) line: not available
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available
NativeMethodAccessorImpl.invoke(Object, Object[]) line: not available
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available
SubtractServiceImpl.subtract(double, double) line: 27
|

 |
まとめ
ここで紹介した SCA アプリケーションの例は概念としては単純ですが、その実装はむしろ複雑です。この計算機アプリケーションが参照する 4 つの異なるサービスは、それぞれに異なる技術 (Java 技術、Web サービス、HTTP、JScript、Groovy) で実装あるいはアクセスされるからです。これまで、一部のアーキテクチャーではこのような異なる種類の技術を統合するのは現実的ではなかったり、技術層とビジネス層がごちゃ混ぜになってしまったりする可能性がありました。なかには、技術ドメインを自分が最もよく知っている技術ドメインに変換するために時間を無駄にしていた開発者もいます。
SCA はそのようなアーキテクチャーとは異なり、既存の技術を利用して、それらの技術を 1 つのアプリケーションに統合することができます。技術は変換も再コーディングもほとんどされずに、そのままの形でインポートされるため、技術の実装はビジネス・ロジックから切り離された状態に保たれることにとなります。そして SCA コンポーネントのどれもが、別のコンポーネントと交換可能であり、新しいバインディングや実装上にホストすることが可能です。しかも、アプリケーション全体への影響はほとんどありません。
SCA のメリットを享受するには多少の犠牲が伴いますが、幸いなことに Tuscany などの SCA ランタイムが、メッセージのルーティング、各種インターフェースの理解、アクセスとデータ・バインディングとのインターフェース、そして多種多様な実装の呼び出しといった作業を受け持ってくれます。事実上、技術に関する多くの問題はアプリケーションから取り除かれ、Apache Tuscany ミドルウェア層に置かれることになります。SCA アプリケーションに関する問題を調べると、最終的な呼び出し経路が多少複雑に見えることもありますが、この記事で説明した SCA の実装例によって、その複雑さはある程度取り除かれたはずです。
ダウンロード | 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|
| Calculator showing various invocations | os-apache-tuscany-sca-sample-calculator.zip | 13KB | HTTP |
|---|
参考文献 学ぶために
製品や技術を入手するために
議論するために
著者について  | |  | Dan Becker は、テキサス州オースティンの IBM Software Division で Java Sound API のさまざまな IBM 実装でのオーディオ・サブシステムを担当しています。その前は、以前の Java 仮想マシンの移植、Netscape Navigator for OS/2 のマルチメディア・プラグイン、OpenDoc、OS/2 Warp バージョン 4.0 のマルチメディア・パーツに取り組んでいました。彼の公式 Web ページ www.io.com/~beckerdo にアクセスしてください。 |
記事の評価
|