Axis開発者ガイド

バージョン1.0

目次

はじめに
一般的なガイドライン
開発環境
プラグイン可能なコンポーネント
   発見
   ロギング/トレーシング
設定プロパティ
例外ハンドリング
コンパイルと実行
国際化
   メッセージファイルの拡張
テストケースの追加
テストとサンプル構造
ソースコードチェックの追加
デバッグ
JAX-RPC互換性テストの実行
 

はじめに

このガイドはAxisの開発コードに関するトピックを集めたものです。

一般的ガイドライン

開発環境 Axisの開発には以下のパッケージが必要です:


Axisのjarファイルは、xml-axis/java/build/libディレクトリにビルドされます。以下は、私がコード開発する際に使用するCLASSPATH例です:

D:\\xerces\\xerces-1_4_2\\xerces.jar
G:\\junit3.7\\junit.jar
G:\\xml-axis\\java\\build\\lib\\commons-discovery.jar
G:\\xml-axis\\java\\build\\lib\\commons-logging.jar
G:\\xml-axis\\java\\build\\lib\\wsdl4j.jar
G:\\xml-axis\\java\\build\\lib\\axis.jar
G:\\xml-axis\\java\\build\\lib\\log4j-1.2.4.jar
G:\\xml-axis\\java\\build\\classes
プロキシサーバ経由でインターネットに接続している場合は、環境変数を設定する必要があり、それによりAxisのテストは同じことを行います。例えば、ANT_OPTSを以下のように設定します:
-Dhttp.proxyHost=proxy.somewhere.com -Dhttp.proxyPort=80 -Dhttp.nonProxyHosts="localhost"

プラグイン可能なコンポーネント

Axisアーキテクチャガイドに、プラグイン可能なコンポーネントの要件が説明されています。

発見

axis-specificコンポーネントファクトリは、以下の形式で生成します:
    org.apache.axis.components.<componentType>.<factoryClassName>
例えば、org.apache.axis.components.logger.LogFactoryは、ロガーのコンポーネント/サービスに対するファクトリ、もしくは、発見メカニズムです。

org.apache.axis.components.imageパッケージは、AXISで使用される異なる画像ツールにおけるファクトリとサポートするクラスの両方を説明しています。これは、外部ツール使用するプラグイン可能なコンポーネントの表現で、AXISの最小要件を満たすために制限されたインタフェースのみを提供するために、'薄い'ラッパをAXISに隠して分離します。これは、将来のデザイナや実装者に、これらのツールにおけるAXIS固有の要件の明示的な理解を得ることを許します。

ロギング/トレーシング

AXISのロギングとトレーシングは、Jakarta Commonsプロジェクトのロギングコンポーネント、あるいは、Jakarta Commons Logging (JCL) SPIをベースにしています。JCLは、Log4JAvalon LogKitJDK 1.4を含む、他のロギングツールのための薄いラッパとしての実装を持つLogインタフェースを提供します。このインタフェースは、Log4JとLogKitとでほぼ同等のマッピングを行います。

Logger SPIの使用

JavaクラスからJCL SPIを使うためには、以下のimport文を使います:

各クラス定義に対して、log属性を以下のように宣言し、初期化します:

メッセージは、priorityに対応するメソッドを呼び出すことにより、logのようなloggerにログ出力されます。Logインタフェースは、logへログ/トレースメッセージを出力するための以下のメソッドを定義しています:

これらのメソッドの意味は、結果的にはLogインタフェースの実装を定義することですが、メッセージの重要性は上記のリストに示される通りの順番であることが期待されています。

ロギングメソッドに加えて、以下のものが提供されています。

これらは通常は、ロギングのサポートを実行するのに必要なだけのコードをガードするために使われ、(ロギングが無効とされる)一般的なケースでは好ましくない実行時のオーバーヘッドがあります。

ガイドライン

メッセージの優先度
ログメッセージが内容と重要性において適切であることを保証することは重要です。以下のガイドラインが提案されます:

Loggerの設定

Jakarta Commons Logging (JCL) SPIは、異なるロギングツールキットを使用するように設定できます。JCLにより、どのロガーを使用するかの設定方法については、AXISシステム統合ガイドを参照して下さい。

JCLの振る舞いの設定は、使用するロギングツールキットに完全に依存します。JCL SPI(と、AXIS)は、Log4Jが(CLASSPATH内で)有効であれば、デフォルトでそれを使用します。

Log4J
Log4Jは、AXISにとって好ましい/デフォルトのロガーなので、開発者が進んでいくために、ここにいくつかの詳細を示します。

システムプロパティやプロパティファイルを使用してLog4Jを設定します:

設定プロパティ

内部設定の主要点として、AXISは、処理中にシステムプロパティの使用から移行します。System.getProperty()の呼び出しを避け、代わりにAxisProperties.getPropertyを呼び出します。AxisProperties.getPropertyは、System.getPropertyを呼び出し、設定情報のその他のソースを(最終的に)照会します。

この中心点アクセスの使用により、1つのJVMで複数のAXISエンジンを良好にサポートするように、グローバルな設定システムを再設計することができます。

例外ハンドリング

AXIS例外ハンドリングのガイドラインは、例外ハンドリングにおける最良事例を基礎としています。これらのガイドラインには、AXIS特有の細かい点もありますが、基本的にどのようなプロジェクトにも当てはまります。これには、2つの理由があります。1つ目は、Apache/Jakartaガイドラインにはどこにも記載されていないため(もしくは、見つからないため)です。2つ目は、これらのガイドラインを守ることは、企業レベルのミドルウェアにとって極めて重要と考えられるためです。

これらのガイドラインは、基本的にプログラミング言語に依存しません。これらは経験を元にしていますが、長年に渡って無垢な人(?)に目を向けさせるために、適切なクレジットはScott MeyersによるMore Effective C++にしておいて下さい。

最後に、これらはガイドラインです。これらのガイドラインに対する例外があった際は常に、(これらのガイドラインどおり)質問される全ての事項がコード内にコメント形式で書かれています。

コンパイルと実行

アプリケーションをビルドしてテストを実行するために、Antによって使用される初期の'make'ファイルは、xml-axis/java/build.xmlです。build.xmlファイルは、Antのビルドターゲットを定義しています。より詳細な情報は、build.xmlファイルを参照して下さい。いくつかの便利なターゲットを紹介します。
  ソースコードのコンパイル:
cd xml-axis/java
ant compile
テストの実行:
cd xml-axis/java
ant functional-tests
注意:これらのテストはサーバのポート番号8080で開始します。(Tomcatなどの)Webアプリケーションサーバがこのポートを使用していることによってテストがクラッシュする場合、このポート番号を変更するか、テストを実行している間はWebアプリケーションサーバを停止して下さい。

新しいコードを挿入する前に、ant functional-testsant all-testsを実行して下さい。

国際化

(エラーメッセージやデバッグ情報などの)テキストを生成するソースコードを変更する場合、テキストが正しく翻訳されることを保証するために、以下のガイドラインに従わなければなりません。

開発者ガイドライン

  1. テキスト文字列は、プロパティとしてresource.propertiesファイル(xml-axis/java/src/org/apache/axis/i18n/resource.properties)に追加されるべきです。いくつかのユーティリティアプリケーション(例えば、tcpmon)は、独自のリソースプロパティファイル(tcpmon.properties)を持っていることに注意して下さい。

  2.  
  3. resource.propertiesファイルは、翻訳と使用方法の指示を含んでいます。 メッセージリソースファイルの項目は、<key>=<message>形式です。 以下は、メッセージの例です:
  4. sample00=My name is {0}, and my title is {1}.
     

    1. sample00は、コードがこのメッセージにアクセスするために使用するキーです。
    2. = 以降のテキストはメッセージテキストです。
    3. {number}構文は、挿入される場所を定義します。
  5. コードは、スタティックメソッドorg.apache.axis.i18n.Messages.getMessageを使用して、テキストを取得して挿入を追加するべきです。使用例は以下です:
  6. Messages.getMessage("sample00", "Rich Scheuerle", "Software Developer");
     

  7. プロパティファイルの全てのキーは、<string><2-digit-suffix>構文を使用するべきです。

  8.  
    1. プロパティファイルのメッセージテキストを変更してはいけません。メッセージはコード内の複数個所で使用される場合があります。また、翻訳は新しいキーにおいてのみ行われます。

    2.   コードの変更がメッセージの変更を必要とする場合は、数字2桁のサフィックスを増加させた新規項目を作成します。
       
    3. 全ての新規項目は、翻訳を簡単にするためにファイルの最後に置かれるべきです。

    4.  
    5. 古いデータのプロパティファイルを削除したい場合があるかもしれませんが、これはメジャーリリースでのみ行われるべきです。

実例

以下の文を考えてみます:

        if ( operationName == null )
            throw new AxisFault( "No operation name specified" );

項目をorg/apache/axis/i18n/resource.propertiesに追加します:

       noOperation=No operation name specified.

読み込むためにコードを変更します:

        if ( operationName == null )
            throw new AxisFault(Messages.getMessage("noOperation"));

インタフェース

AXISは、プロパティファイルとメッセージ文字列へアクセスするために標準Java国際化クラスのjava.util.ResourceBundleを使用し、変数を使用して文字列を形式化するためにjava.text.MessageFormatを使用します。AXISは、ResourceBundleクラスとMessageFormatクラスの両方を管理するために、1つのorg.apache.axis.i18n.Messagesクラスを提供しています。Messagesクラスのメソッドは、以下になります:

public static java.util.ResourceBundle getResourceBundle();

public static String getMessage(String key) throws java.util.MissingResourceException;

public static String getMessage(String key, String var) throws java.util.MissingResourceException;

public static String getMessage(String key, String var1, String var2) throws java.util.MissingResourceException;

public static String getMessage(String key, String[] vars) throws java.util.MissingResourceException;

AXISプログラマは、Messages.getResourceBundle()を呼び出すことによってリソースバンドルを直接操作することができますが、2つの理由からgetMessage()メソッドを代わりに使用します:

  1. ショートカットです。
      Messages.getResourceBundle().getString("myMsg00");
    を呼び出すよりも
      Messages.getMessage("myMsg00");
    を呼び出す方が簡潔なため。
  2. getMessageメソッドは、メッセージに変数を埋め込むことができるだめ。

getMessageメソッド

変数を埋め込まないメッセージ
    myMsg00=This is a string.
の場合には、単純に
    Messages.getMessage("myMsg00");
を呼び出します。


変数があるメッセージの場合、"{X}"シンタックスを使用します。ここで、Xは、0から始まる変数の番号です。例えば:

    Messages.getMessage("myMsg00","name", "Russell");
となっていた場合、
    Messages.getMessage("myMsg00", new String[] {"name", "Russell"});
を呼んだ結果の文字列は、"My name is Russell."となります。

String配列のgetMessageを呼ぶこともできます:

    Messages.getMessage("myMsg00", new String[] {"name", "Russell"});


String配列版のgetMessageは全てに適用できますが、ほとんどのメッセージの変数は0、1、もしくは、2つなので、その他のgetMessageメソッドは、String配列版の複雑さを避けるための利便性として提供されています。

リソースが見つからない場合、getMessageメソッドは、MissingResourceExceptionを投げることに注意して下さい。そして、引数の数よりも{X}項目が多い場合、ParseExceptionが投げられます。これらの例外は、RuntimeExceptionなので、呼び出し元は明示的にキャッチすべきではありません。

リソースバンドルのプロパティファイルは、org/apache/axis/i18n/resource.propertiesです。

メッセージファイルの拡張

一般的にAXIS内では、全てのメッセージがorg.apache.axis.i18n.resource.propertiesに設定されています。AXISを統合したりサードパーティが拡張するために、このファイルを修正することなくメッセージを拡張する機能があります。詳細は、統合ガイドを参照して下さい。

テストケースの追加

テストとサンプル構造も参照して下さい。

編集者注意:我々は、テスト追加の能率化や簡素化のために、もっと努力が必要です。また、テストの増加に従い、テストを分類することを考えなければなりません。
 

Axisを変更した場合、その変更を使用するテストを追加して下さい。それはなぜでしょう?


いくつかの一般的な原則:


テストをビルドする1つの方法は、既存のテストをカットアンドペーストして、あなたの要求に合うようにテストを変更することです。このアプローチはテスト種類の増加に従い、複雑さを増します。

参照するための"非WSDL"の良好なテストは、test/saajです。

WSDLテストの生成 私が、シーケンステストを生成した際の工程を示します。WSDLファイルからコードを生成し、妥当性テストのシーケンスを実行します。
 
  1. xml-axis/java/test/wsdl/sequenceディレクトリを生成。

  2. Webサービスを定義しているSequenceTest.wsdlを生成。

  3. Javaファイルを生成するためにWsdl2javaのエミッタを実行:
  4. java org.apache.axis.wsdl.Wsdl2java -t -s SequenceTest.wsdl

    1. -tオプションは、テストハーネスへのフックとなる*TestCase.javaファイルを、エミッタに生成させます。このファイルは変更を追加することなく実行可能です。*TestCase.javaファイルを、あなたのWSDLファイルと同じディレクトリにコピーして下さい。(理想的には、あなたのディレクトリには変更されたJavaファイルのみが必要となります。したがって、このファイルは必要とされませんが、テストケースを実行するためには、あなたの<wsdl2java ...>節を変更することを確認して下さい(以下で説明します)。
    2. -sオプションは、エミッタに*SOAPBindingImpl.javaを生成させます。このJavaファイルはそのサービスのための空のメソッドを含みます。あなたは多分、あなた独自のロジックでそれらを埋めたいでしょう。あなたのWSDLファイルと同じディレクトリに、*SOAPBindingImpl.javaファイルをコピーして下さい。(このJavaファイルに変更が必要ない場合は、それを保存する必要はありません。しかし、<wsdl2java ...>節がスケルトンを生成することを確認する必要があります)。
    3. 変更を必要としない全てのJavaファイルを削除します。したがって、あなたのディレクトリには3つのファイルがあることになります(WSDLファイル、*TestCase.java、*SOAPBindingImpl.java)。私のシーケンステストでは、私が必要とするいくつかの追加ロジックのために、その他のファイルがあります。

  5. test/wsdl/sequence/build.xmlファイルは、このテストのビルドを制御します。"compile"ターゲットを探して下さい。Wsdl2javaコードを実行する節を追加します。test/wsdl/roundtrip/build.xmlファイルを参照すると良いでしょう(wsdl2javaやjava2wsdlを多く呼び出しています)。SequenceTestのためのものを示します:
  6.     <!-- Sequence Test -->
        <wsdl2java url="${axis.home}/test/wsdl/sequence/SequenceTest.wsdl"
                   output="${axis.home}/build/work"
                   deployscope="session"
                   skeleton="yes"
                   messagecontext="no"
                   noimports="no"
                   verbose="no"
                   testcase="no">
            <mapping namespace="urn:SequenceTest2" package="test.wsdl.sequence"/>
        </wsdl2java>
    新しいbuild.xmlファイル内のrunターゲットが可能です。execute-Componentターゲットと(直ぐに導入するなら)execute-Simple-Testターゲットから選択する必要があります。execute-Componentは、テストを実行する前にTCPサーバとHTTPサーバをセットアップし、必要となるサービスや配備を同様に操作します。execute-Simple-testは、単純に生のテストクラスファイルを呼び出します。

  7. 終わりです。検証するためにant functional-tests を実行して下さい。あなたのテストをチェックインして下さい。

  8.  

テスト構造

テストとサンプルの再設計文書は、こちらです。

Axis 1.0 RC1以降で、"コンポーネント化された"テスト構造へと移行されました。1つの高次レベルの大きな再帰的関数を持つ代わりに、test/**配下やsamples/**配下の末端レベルに小さくて単純な"コンポーネント"build.xmlファイルがあります。

これらの"コンポーネント"ファイルは、共通のレイアウトを持ちます。主なターゲットには、以下があります:

"サンプル"テストのXMLファイルは、test/templateTestにあります。

ソースコードチェックの追加

Axisのビルドは、メッセージに国際化された文字列を使用しているかなどの規約が守られているかを確実に確認するために、ソースディレクトリ(java/src)のファイルをいくらか自動化させてチェックします。

規約を正規表現として表現できる場合、java/test/utils/TestSrcContent.javaを更新することでビルド時にチェックを強制することができます。

必要なことの全ては、パターンにスタティックなFileNameContentPattern配列を追加することです。各パターンには、3つのパラメータがあります:

  1. 確認するファイル名の適合させるパターン
  2. 選択されたファイルを検索するためのパターン
  3. パターンを使用するかを指定するboolean(一般的に、指定しない場合はfalseになります)

正規表現記法の分かりやすい要約は、Jakarta OROのjavadocで提供されています。

デバッグ

機能テストをモニタするためのtcpmonの使用

functional-tests(あるいは、all-tests)を実行している間に、メッセージをモニタする簡単な方法を示します。
tcpmonがポート8080をリッスンするようにして開始し、異なるポートへフォワードします。

java org.apache.axis.utils.tcpmon 8080 localhost 8011
あなたのテストを実行しますが、SimpleAxisServerにはフォワードされているポートを使用し、functional-testsで失敗が起きても継続するように指示して下さい。
ant functional-tests -Dtest.functional.SimpleAxisPort=8011 -Dtest.functional.fail=no
全てのテストのSOAPメッセージが、tcpmonのウィンドウに現れるでしょう。

tcpmonは、AXISユーザガイドに詳しく説明されています。

機能テストをモニタするためのSOAPモニタの使用

(Tomcatなど)Webアプリケーションサーバを使用するWebアプリケーションとして実行しているコードをデバッグする際、SOAPの要求メッセージと応答メッセージを見るためのSOAPモニタユーティリティも使用することができます。
WebブラウザのウィンドウでSOAPモニタアプレットをロードすることによってSOAPモニタユーティリティが開始されます:

http://localhost:<port>/axis/SOAPMonitor
テストを実行すると、SOAPメッセージがSOAPモニタウィンドウに表示されます。

SOAPモニタの詳細は、AXISユーザガイドで説明されています。

単一機能テストの実行

1つのウィンドウでサーバをスタートします:
java org.apache.axis.transport.http.SimpleAxisServer -p 8080
別ウィンドウで、まず、あなたがテストするサービスを配備します:
java org.apache.axis.client.AdminClient deploy.wsdd
そして、あなたのテストをJUnitのユーザインタフェースを指定して起動します。例えば、マルチスレッドテストケースの実行は:
java junit.swingui.TestRunner -noloading test.wsdl.multithread.MultithreadTestCase

デバッグ出力の作動

このセクションは、AXISのデフォルトのロガー:Log4Jについて説明します。Log4Jの追加的な情報については、ロガーの設定を参照して下さい。

一時出力の記述

AXISは多くのオープンソースと他のWebアプリケーションで使われることを目標にしていることを覚えておいて下さい。したがって、善良な市民になる必要があります。System.out.printlnSystem.err.printlnで出力を書き出すことは避けられるべきです。

開発者は、システムをデバッグしたり解析している際に、System.out.printlnを使用したい思うかもしれません。もしその方法を選んだら、util/TestSrcContentテストを無効にする必要があります。このテストは、System.out.printlnSystem.err.printlnの回避を強制します。あなたがコードをチェックインして戻す前にそれらの文を削除する必要があることになります。

一方で、我々はあなたに、少し時間を取ってデバッグ文を使うことを強く勧めます:log.debug("reasonably terse and meaningful message")。もし、デバッグメッセージが問題を理解するために有用であれば、将来もあなたや仲間によって有用となるでしょう。

JAX-RPC互換性テストの実行

JAX-RPCには、仕様と共に、JAX-RPC専門家グループ(と関係者?)メンバが利用可能な技術互換性キット(TCK)があります。

このキットは、zipファイルを指定ディレクトリに解凍することで利用できます。インストール方法は、docsディレクトリにあるJAX-RPCリリースノート文書に書かれています。Webブラウザでdocsディレクトリ内のindex.htmlファイルを開けば、このキットで供給されている全ての文書の一覧を見ることができます。

このキットには、互換性テストを実行するために使用するJavaTestテストハーネスが含まれていることに注意して下さい。

このテストを実行するための詳細な情報が必要であれば、ここに追加して下さい。


本文書は、日本Apache XMLプロジェクト(佐藤 誠/石神 覚司)により翻訳されました。
翻訳に対するコメントは、jaxmldev@xml.gr.jpに送って下さい。