本文へジャンプ

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。プロフィールで選択した情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

  • 閉じる [x]

developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む


送信されたすべての情報は安全です。

  • 閉じる [x]

クラスワーキング・ツールキット: アスペクトを動かす

アスペクトでコード汚染をクリーンアップできるのか? ロギングにAspectWerkzフレームワークを使うことが第一歩

Dennis Sosnoski, President, Sosnoski Software Solutions, Inc.
Photo of Dennis Sosnoski
Dennis Sosnoskiはシアトル地域にあるJava技術のコンサルティング会社、Sosnoski Software Solutions, Inc.の創立者で、主席コンサルタントでもあり、またXMLやWebサービスに関するトレーニングやコンサルティングの専門家でもあります。彼のプロとしてのソフトウェア開発経験は30年以上に渡り、ここ数年はサーバー側のXML技術やJava技術に注力しています。Dennisは、全米各地で行われる会議で頻繁に講演を行っています。また、Javaクラスワーキング技術を基に構築された、オープンソースのJiBX XML Data Bindingフレームワークの中心開発者でもあります。

概要: AOP(aspect-oriented programming: アスペクト指向プログラミング)では、特定なクラスやパッケージに対してではなく、アプリケーション全体に適用される機能を分離することによって、コードをきれいに保つことができる、と約束しています。ロギングは、そうした種類の機能として一般的なものの一つです。ロギングにとって、AOPは役立つものなのでしょうか。この記事では、ソフトウェア開発者であり、熱烈なAOP支持者であるDennis Sosnoskiが、AspectWerkzフレームワークを使って、その真偽を見て行きます。

日付:  2005年 3月 08日
レベル:  初級 この記事の原文:  英語
アクティビティー: 3001 ビュー
お気軽にご意見・ご感想をお寄せください: 


私はかつてJava programming dynamics(参考文献)というシリーズの中で、クラスワーキングの手法を使うことによって、プログラムの振る舞いにシステム的変更が行えることを示しました。この種の手法は、Java™プラットフォームでのAOPで行われている大部分の作業の基礎となっています。この記事では、同じようなシステム的変更をプログラムの振る舞いに加えるために、クラスワーキングの上に高位レイヤーを構築するAOPフレームワークを使って、使いやすさを向上させる方法を説明します。

AspectWerkzの紹介

Javaプラットフォームでは、数多くのAOPフレームワークを使うことができます。このシリーズの記事では、AspectWerkzフレームワークを使うことにしました。これは、BEA Systemsがスポンサーであるオープンソースのプロジェクトです。AspectWerkzは、Java技術用のAOPとして一番古いわけではありません。一番古いものとしては、IBMがサポートする、Javaプログラミング言語のAspectJエクステンションがあります。しかしAspectWerkzは、標準のJavaコードと組み合わせてAOPを使うための高速で強力、そして柔軟なフレームワークとして、大きな注目を集めているものです。AspectWerkzとAspectJの両チームは最近、合体するという発表を行いました。ですから今後は、両者の最高機能をまとめて1つの製品としたものが見られるようになるでしょう。これについては今後の記事で触れますが、ここではとりあえず、ベースとなるAspectWerkzフレームワークに集中することにします。

注意: AOPの実用的な使い方の紹介として、新しいAOP@Workコラムをぜひ見てください。このコラムは2005の2月に始まり、1年間継続される予定ですが、最先端のAOPエキスパート5人が執筆しており、どの記事にも、皆さんがすぐに応用できるような知識が提供されています。

ロギングは、日々の開発の中でAOP推進者がAOPのアプリケーションをリストアップする時には、必ず取り上げられるようです。ロギングは、典型的な企業アプリケーションのコードの中で、確かに大きな部分にまたがる懸念事項です。また、ロギング・コードはアプリケーションの主目的とは無関係ですが、また同時に、非常にコードの中に侵入しやすいものです。ロギングにはこのような特徴があるため、アスペクトとして構成すべき機能の候補としては理想的です。ここでは、こうした種類の問題領域に対してアスペクトのパラダイムがいかにうまく応用できるかを示すために、ロギングとパフォーマンス・メトリック・アスペクトを組み合わせた実装を見て行きます。


AspectWerkzの基礎

AspectWerkzのWebサイト(参考文献)には、詳細なドキュメンテーションと使用例、そして、AspectWerkzを使った記事へのリングが掲載されています。ここでそれらを再掲することはしませんが、その中で私が最も重要な概念と思うもの、つまりポイントカット(pointcuts)とアスペクト、そしてアドバイスを簡単に紹介しておきましょう。

ポントカットは基本的に、アプリケーション実行の「通常の」(ソースコードで定義された通りの)フローへに割り込み、何か別のことをするための、単なる場所にすぎません。AspectWerkzは、Javaコード構造(例えばメソッド・コールや実行、フィールド取得/設定、例外ハンドラー実行、そして特定な実行パス内のコードを含む組み合わせなど)に結びついた多くの種類のポントカットをサポートしています。

AspectWerkzの用語では、アスペクトはクロスカット・コンサーンのターゲットとして適用される、単なるJavaクラスにすぎません。クラスをアスペクトにするためには、特別なインターフェースの実装は必要ありませんが、アスペクトとしてクラスにアクセスするためには、特定なメソッド・シグニチャーが要求されます。一般的にアスペクト・クラスは、ほとんどの場合AspectWerkzフレームワークでしか使われないため、標準のアプリケーション・クラス階層構造の外に置かれるでしょう。しかし、繰り返しますが、(ランタイムのクラスパスを除き)どこか特別な場所になければならない、ということはありません。

アドバイスはアスペクト・クラスの中のメソッドであり、ポイントカットで行うべき「何か違うこと」として使われます。アドバイスに対するデフォルトのメソッド・シグニチャーは、1つのパラメーターを取ることであり、このパラメーターが、捕捉されるポイントカットに関する情報を提供します。リスト1は、メソッド・コールにおいて前アドバイス、後アドバイスとして使われるべき、1対のメソッドを定義するアスペクト・クラスです。


リスト1. 単純なアドバイス・クラスとアドバイス・メソッド
                
package com.sosnoski.aspectwerkz;
public class TraceAspect
{
    public void beforeMethod(JoinPoint join) {
        System.out.println("Entering method");
    }
    public void afterMethod(JoinPoint join) {
        System.out.println("Leaving method");
    }
}

AspectWerkzは他のメソッド・コール・シグニチャーもサポートしていますが、その設定に関しては少し余分な努力が必要です。そう、設定と言えば、AspectWerkzは次の3つの形式の設定をサポートしていることを最初に言っておくべきでしょう。

  • ソースコードに埋め込まれたJava 5.0アノテーション
  • ソースコードに埋め込まれたJavadocスタイルのアノテーション
  • 外部XMLファイル

私はXML的人間なので(私はdeveloperWorksのXMLゾーンにも定期的に寄稿しています)、この記事ではXMLオプションを使うことにします。リスト2は、リスト1のアドバイスに対するXML設定の例です。


リスト2. XML設定の例
                
<aspectwerkz>
  <system id="AspectWerkzExample">
    <package name="com.sosnoski.aspectwerkz">
      <aspect class="TraceAspect">
        <pointcut name="longMethod"
            expression="execution(long ..(..))"/>
        <advice name="beforeMethod" type="before"
            bind-to="longMethod"/>
        <advice name="afterMethod" type="after"
            bind-to="longMethod"/>
      </aspect>
    </package>
  </system>
</aspectwerkz>

リスト2の設定は、クラス、com.sosnoski.aspectwerkz.TraceAspectの中で実装されている通り、1つのアスペクトを定義しています。このアスペクトに対して、リスト2の設定では、long値(一致対象の表現内の「..」シーケンスはワイルドカードです)を返す任意メソッドの実行を表す1つのポイントカットを定義しており、2つの別々のアドバイス片を、このポイントカットにバインドしています。最初のアドバイスは、そのアドバイス・クラスのbeforeMethod()が実装し、タイプはbefore です(つまり、このアドバイス・メソッドは、ポイントカット・メソッドが実行される前に呼ばれます)。2番目のアドバイスは、afterMethod()が実装し、タイプはafterです(つまり、このアドバイス・メソッドは、ポイントカット・メソッドが実行された後に呼ばれます)。


ログ・オン

さて、AspectWerkzの基本的な概念は理解しましたが、こうした概念をロギング機能にどう適用するのでしょう。この前のセクションでのメソッド・コールの例が、出発点として適当なようです。対象とするメソッド・コールの前と後に、AspectWerkzがそれぞれbeforeMethod()afterMethod()を実行するように設定できれば、これらはアプリケーションの実行トレースとして有効に使えるはずです。

もちろん、実行トレースを有用なものとするためには、最小限の情報しか出力していない、リスト1のメソッドの出力を拡張する必要があります。幸いAspectWerkzには、捕捉されるポイントカットに関する情報に簡単にアクセスできる方法があります。リスト3のコードは、実際のメソッド情報にポイントカットからアクセスする方法を示しています。


リスト3. アドバイス・メソッドが捕捉したメソッドをレポートする
                
package com.sosnoski.aspectwerkz;
public class TraceAspect
{
    public void beforeMethod(JoinPoint join) {
        MethodSignature signature =
            (MethodSignature)join.getSignature();
        System.out.println("Entering method " +
            signature.getName());
    }
    public void afterMethod(JoinPoint join) {
        MethodSignature signature =
            (MethodSignature)join.getSignature();
        System.out.println("Leaving method " +
            signature.getName());
    }
}

この暫定ロギング・コードをテストするために、ちょうど良い再帰的メソッドとして、フィボナッチ数列計算の実装を使います。これをリスト4に示します。


リスト4. フィボナッチ数列の計算
                
package com.sosnoski.aspectwerkz;
public class FiboTest
{
    private long fibo(int value) {
        if (value > 2) {
            return fibo(value-1) + fibo(value-2);
        } else {
            return 1;
        }
    }
    public static void main(String[] args) {
        FiboTest inst = new FiboTest();
        int value = Integer.parseInt(args[0]);
        System.out.println("Fibo[" + value + "] is " +
            inst.fibo(value));
    }
}

このコードを直接実行するのは簡単です。

[dms]$ java -cp classes com.sosnoski.aspectwerkz.FiboTest 6
Fibo[6] is 8

AspectWerkzを使っての実行は、もう少し複雑です。AspectWerkzを使ってアスペクト処理を実装するには、ビルドタイム・クラス・モディフィケーション(build-time class modification)とランタイム・クラス・モディフィケーション(run-time class modification)という、2つの方法があります。この記事では全体を通して、ランタイム版の方を使います。この方法では、AspectWerkzフレームワークの一部として提供されている、カスタムのクラスローダーが必要です。AspectWerkzインストールのホーム・ディレクトリーに対する環境変数を使い、また(リスト2の)XML設定がaspectwerkz.xmlファイルの中にあるとすると、リスト4のコードをAspectWerkzを使ってLinux™版あるいはUNIX®版用に書くと、次のようになります。

[dms]$ $ASPECTWERKZ_HOME/bin/aspectwerkz
   -Daspectwerkz.definition.file=aspectwerkz.xml
   -cp classes com.sosnoski.aspectwerkz.FiboTest 6

この結果の出力も、ずっと長くなります。ここでは(そして他の例でも)、AspectWerkzが出力するスタートアップ情報は無視し、私のアドバイスが生成する出力のみを示します。出力は、リスト5のようになります。


リスト5. アドバイスを使った計算結果
                
Entering method fibo
Entering method fibo
Entering method fibo
Entering method fibo
Entering method fibo
Leaving method fibo
Entering method fibo
Leaving method fibo
Leaving method fibo
Entering method fibo
Leaving method fibo
Leaving method fibo
Entering method fibo
Entering method fibo
Leaving method fibo
Entering method fibo
Leaving method fibo
Leaving method fibo
Leaving method fibo
Entering method fibo
Entering method fibo
Entering method fibo
Leaving method fibo
Entering method fibo
Leaving method fibo
Leaving method fibo
Entering method fibo
Leaving method fibo
Leaving method fibo
Leaving method fibo
Fibo[6] is 8

きれいにする

リスト5は、リスト3のアドバイス・メソッドが呼ばれていることを示していますが、実行されているアプリケーションに関しては、大して有効な情報を示していません。この欠点を修正しましょう。メソッド・コールのネストを段付けして示すように、また、やり取りされる値も出力するように、アドバイスを変更します。そのために、アドバイスのタイプも、aroundアドバイス・タイプという別のタイプに変更します。リスト6は、この修正を行ったコードを示しています。


リスト6. 段付けと値の印刷を行うアドバイス・メソッド
                
private int m_nestingDepth;
private void indent() {
        for (int i = 0; i < m_nestingDepth; i++) {
            System.out.print(' ');
        }
    }
    
private void printCall(JoinPoint call) {
    MethodSignature signature =
        (MethodSignature)call.getSignature();
    System.out.print(signature.getName());
    System.out.print('(');
    MethodRtti rtti = (MethodRtti)call.getRtti();
    System.out.print(rtti.getParameterValues()[0]);
    System.out.print(')');
}
public Object traceLong(JoinPoint join) throws Throwable {
        // print entering information
    indent();
    System.out.print("Entering method ");
    printCall(join);
        // execute the joinpoint method
    m_nestingDepth++;
    Object result = join.proceed();
    m_nestingDepth--;
        // print exiting information
    indent();
    System.out.print("Leaving method ");
    MethodSignature signature =
        (MethodSignature)join.getSignature();
    System.out.print(signature.getName());
    System.out.print('<');
    System.out.println(result);
        // return result from method call
    return result;
}

名前から想像できるかも知れませんが、aroundアドバイスは、ポイントカット実行の前後を囲みます。このアドバイスは、ポイントカットを実行すべき時に呼ばれますが、ポイントカットを実際にいつ実行するのか、さらには、実際に実行するかどうかさえも決めるだけの柔軟性を持っています。リスト6のコードでは、aroundアドバイスの処理を簡単にしてあります。ここではアドバイス・コード(traceLong()メソッド)はまず、カレントのネスト・レベルまで段付けされた、メソッド名と引数の出力から始めます。次にそのメソッドを呼んで結果を保存した後、カレントのネスト・レベルまで段付けされたメソッド名と戻り値を出力して終了します。

XML設定は、この新しいアドバイスを使うように調整する必要がありますが、これは簡単な変更です。下記は、変更したファイルからのaspect要素です(変更は太字で示してあります)。

    <package name="com.sosnoski.aspectwerkz">
      <aspect class="TraceAspect">
        <pointcut name="longMethod"
            expression="execution(long ..(..))"/>
        <advicename="traceLong" type="around"
            bind-to="longMethod"/>
      </aspect>
    </package>

リスト7は、この新しいアドバイスを使って生成された出力です。


リスト7. 段付けと値の印刷を行う出力
                
Entering method fibo(6)
 Entering method fibo(5)
  Entering method fibo(4)
   Entering method fibo(3)
    Entering method fibo(2)
    Leaving method fibo<1
    Entering method fibo(1)
    Leaving method fibo<1
   Leaving method fibo<2
   Entering method fibo(2)
   Leaving method fibo<1
  Leaving method fibo<3
  Entering method fibo(3)
   Entering method fibo(2)
   Leaving method fibo<1
   Entering method fibo(1)
   Leaving method fibo<1
  Leaving method fibo<2
 Leaving method fibo<5
 Entering method fibo(4)
  Entering method fibo(3)
   Entering method fibo(2)
   Leaving method fibo<1
   Entering method fibo(1)
   Leaving method fibo<1
  Leaving method fibo<2
  Entering method fibo(2)
  Leaving method fibo<1
 Leaving method fibo<3
Leaving method fibo<8
Fibo[6] is 8

賢くする

リスト7の出力であれば、多少使い道がありそうに見えますが、選択性に欠けるのが難です。フィボナッチ数列の指数に、もっと大きな数字(例えば12)を使ってこのコードを実行すると、出力が延々と上にスクロールして行くのを眺める羽目になるでしょう。有用なログ・アスペクト開発の最終ステップとして、出力をうまくフィルターする実装をしてみましょう。

また、実行に一番長く時間がかかるメソッド・コールはどれかが分かるように、ログの実行パスと関連パフォーマンス・メトリックスも得られるようにしたいと思います。ここで使う手法は、私がJava programming dynamics(参考文献)の中でダイレクト・クラスワーキングを使って説明した手法と似ており、java.lang.System.currentTimeMillis()時間値に基づいて行う方法です。このタイマーは高精度なものではありません。Microsoft® Windows®での分解能は約17 ms、私のLinuxシステムでは 1 ms です。ただし、このタイマーは標準Javaプラットフォームであれば必ず使え、デモ用程度でには十分便利なものです。(次回は、タイマーの分解能を上げる方法を議論する予定です。)メソッド・コールにかかった時間で実行トレースをフィルターすれば、面白い結果が出るはずです。

出力の構成を同じに保つため、この、時間ベースのフィルタリングは、少し複雑になります。まず、そのメソッドの要した時間がフィルターを通すのに十分かどうかが分かるまで、各メソッド・コールに対する「入力行」の出力を遅らせる必要があります。これ自体は大したことはありませんが、メソッド情報を本当に出力する段になると、それを囲んでいるメソッド・コールそれぞれに対する入力行を、まず出力しなければなりません。そのためには、まだ出力していないメソッドに対するエントリー情報のリストを保持する必要があり、しかも、カレントのメソッドに対するエントリー情報を出力する前に、これら全てを適切に段付けして吐き出す必要があります。この、未出力メソッドのリストを使うように修正した、新しいアドバイス・メソッドをリスト8に示します。


リスト8. タイミング・フィルターを持つアドバイス・メソッド
                
private ArrayList m_unprintedCalls = new ArrayList();
    
private void indent(int depth) {
    for (int i = 0; i < depth; i++) {
        System.out.print(' ');
    }
}
public Object traceTimed(JoinPoint join) throws Throwable {
        // add joinpoint to list pending print
    m_pendingPrints.add(join);
        // time joinpoint execution
    long start = System.currentTimeMillis();
    m_nestingDepth++;
    Object result = join.proceed();
    m_nestingDepth--;
        // remove joinpoint if still on pending list
    //  (will always be last in list)
    boolean entered = true;
    if (m_pendingPrints.size() > 0) {
        m_pendingPrints.remove(m_pendingPrints.size()-1);
        entered = false;
    }
        // check if execution time above cutoff
    long time = System.currentTimeMillis() - start;
    if (time > 1) {
            // print all unprinted "entering" lines
        int count = m_pendingPrints.size();
        for (int i = 0; i < count; i++) {
                // print entering information for nesting call
            //  (nesting depth based on start of pendings)
            indent(m_nestingDepth-count+i);
            JoinPoint prior =
                (JoinPoint)m_pendingPrints.get(i);
            System.out.print("Entering ");
            printCall(prior);
            System.out.println();
        }
            // clear all pendings now that they're printed
        m_pendingPrints.clear();
            // print exiting information including time
        indent();
        System.out.print("Leaving ");
        printCall(join);
        System.out.print('=');
        System.out.print(result);
        System.out.print(" took ");
        System.out.print(time);
        System.out.println(" ms.");
    }
        // return result from joinpoint execution
    return result;
}

traceLong()の代わりにtraceTimed()アドバイス・メソッドを使うようにXML設定ファイルを修正した後、同じ引数値「6」を使ってこれを実行すると、トレース情報は全く見えなくなります。これは、全体を実行してもタイマーの最小時間以内であるためです。「6」の代わりに値「15」を使うと、リスト9に示すような出力が得られます。


リスト9. タイミング・フィルターを持つ出力
                
Entering fibo(15)
 Entering fibo(14)
  Entering fibo(13)
   Entering fibo(12)
    Leaving fibo(11)=89 took 2 ms.
    Leaving fibo(10)=55 took 2 ms.
   Leaving fibo(12)=144 took 11 ms.
   Entering fibo(11)
    Leaving fibo(10)=55 took 2 ms.
    Leaving fibo(9)=34 took 2 ms.
   Leaving fibo(11)=89 took 5 ms.
  Leaving fibo(13)=233 took 19 ms.
  Entering fibo(12)
   Leaving fibo(11)=89 took 2 ms.
   Entering fibo(10)
    Entering fibo(8)
     Entering fibo(6)
      Leaving fibo(4)=3 took 2 ms.
     Leaving fibo(6)=8 took 4 ms.
    Leaving fibo(8)=21 took 6 ms.
   Leaving fibo(10)=55 took 6 ms.
  Leaving fibo(12)=144 took 10 ms.
 Leaving fibo(14)=377 took 29 ms.
 Entering fibo(13)
  Entering fibo(12)
   Leaving fibo(11)=89 took 2 ms.
   Leaving fibo(10)=55 took 2 ms.
  Leaving fibo(12)=144 took 6 ms.
  Entering fibo(11)
   Leaving fibo(10)=55 took 2 ms.
  Leaving fibo(11)=89 took 3 ms.
 Leaving fibo(13)=233 took 9 ms.
Leaving fibo(15)=610 took 95 ms.
Fibo[15] is 610

リスト9の出力こそ、私が欲しかったものです。では、フィボナッチ数列を卒業し、本物のアプリケーションに移る時です。それを次回に説明しましょう。


次回は

このコラムでは、AspectWerkzを使いながら、パフォーマンス・メトリックス機能を持つ基本的な実行トレースの実装方法を見てきました。次回は、この概念をさらに推し進め、トレース・アスペクトを拡張します。そしてトレース・アスペクトに組み込みのロギングを、実世界の複雑なフレームワークに応用し、アスペクト手法がうまく行く場合と、うまく行かない場合とを見て行きます。アスペクトは、ロギング・コードの汚染から私達を守ってくれるのでしょうか。次回の記事にご期待ください。



ダウンロード

内容ファイル名サイズダウンロード形式
ソース・コード cwt-source.zip6.72KBHTTP

ダウンロード形式について


参考文献

  • この記事の先頭、または最後にあるアイコンCodeをクリックして(またはダウンロード・セクションを見てください)、この記事で使用しているコード例をダウンロードしてください。

  • Dennis Sosnoskiによる、クラスワーキング・ツールキット・シリーズ の全記事を読んでください(日本語に翻訳されていない記事もあります)。

  • AspectWerkzについて詳しく知るためには、このプロジェクトのWebサイトを見てください。豊富なドキュメンテーションや、様々な記事へのリンクが網羅されています。

  • Nicholas Lesieckiによるアスペクト指向プログラミングで、モジュール性を改善する(developerWorks, 2002年1月)を読んで、Java言語用のAspectJアスペクト指向エクステンションについて学んでください。

  • Nicholas Lesieckiは、AOPの実際的な使い方に焦点を当てた、新しいAOP@Workシリーズの執筆チームのリーダーとなっています。

  • Filippo DiotaleviによるAOPを使いコントラクトを実施する(developerWorks, 2004年7月)を読んで、コンポーネント間のアグリーメントのバインディングにとって、AOPがどれほど強力かを学んでください。

  • コンポーネントに柔軟性がなくて困っているのであれば、Andrew GloverによるAOPが密結合の憂うつさを取り除く(developerWorks, 2004年2月)が良いヒントになるかも知れません。

  • Gary PolliceによるA look at aspect-oriented programming(developerWorks, 2004年1月)はAOPの詳細以上の話題、つまりソフトウェア開発プロセスにもたらす影響やAOPが直面する困難などについて議論しています。

  • 既存のシステムを理解し、維持する上でAOPがどのように役立つかを、Abhijit BelapurkarがレガシーJavaアプリケーションの保守にAOPを使用する(developerWorks, 2004年3月)の中で解説しています。

  • この記事の著者のDennis Sosnoskiによる、Javaプログラミング・ダイナミックス・シリーズの全記事を読んで、Javaのクラス構造、リフレクション、クラスワーキングなどを知るツアーに出かけてください(日本語に翻訳されていない記事もあります)。

  • developerWorksのJava technologyゾーンには、Java技術に関する資料が他にも豊富に用意されています。技術的なドキュメンテーションや、ハウツー記事、教育資料、ダウンロード、製品情報など、様々な情報を得ることができます。

  • New to Java technologyには、Javaプログラミングを始めるための助けとなる最新情報が用意されていますので、ご覧ください。

  • Developer Bookstoreには、Java関連の書籍をはじめ、広範な話題を網羅した技術書が豊富に取り揃えられていますので、ぜひご利用ください。


著者について

Photo of Dennis Sosnoski

Dennis Sosnoskiはシアトル地域にあるJava技術のコンサルティング会社、Sosnoski Software Solutions, Inc.の創立者で、主席コンサルタントでもあり、またXMLやWebサービスに関するトレーニングやコンサルティングの専門家でもあります。彼のプロとしてのソフトウェア開発経験は30年以上に渡り、ここ数年はサーバー側のXML技術やJava技術に注力しています。Dennisは、全米各地で行われる会議で頻繁に講演を行っています。また、Javaクラスワーキング技術を基に構築された、オープンソースのJiBX XML Data Bindingフレームワークの中心開発者でもあります。

不正使用の報告のヘルプ

不正使用の報告

ありがとうございます。 このエントリーは、モデレーターの注目フラグが設定されました。


不正使用の報告のヘルプ

不正使用の報告

不正使用の報告の送信に失敗しました。


developerWorks: サイン・イン


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 利用条件

 


お客様が developerWorks に初めてサインインすると、プロフィールが作成されます。 プロフィールで選択した情報は公開されますが、いつでもその情報を編集できます。 お客様の姓名(非表示設定にしていない限り)とディスプレイ・ネームは、投稿するコンテンツと一緒に表示されます。

表示名をお選びください

developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

(半角英数字で3文字以上31文字以下にする必要があります)


「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 利用条件

 


この記事を評価する

コメント

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Java technology
ArticleID=219468
ArticleTitle=クラスワーキング・ツールキット: アスペクトを動かす
publish-date=03082005
author1-email=dms@sosnoski.com
author1-email-cc=