目次


Java Integration ステージにおけるユーザコードのデバッグ

Comments

Java Integration ステージ

IBM InfoSphere Information Server は、企業内に散在する膨大かつ多種多様な情報資産から、より価値のある情報を引き出すためのソフトウェア・プラットフォームであり、データを加工・変換する ETL (Extract, Transform, Load) 機能を提供する IBM InfoSphere DataStage (以下、DataStage) をはじめとする機能群が有機的に結合されたスイート製品です。DataStage 機能を使うことにより、簡単で使い易い GUI 上でステージと呼ばれる部品を組み合わせることにより ETL ジョブを簡単に作成・実行できます。

昨今、クラウドコンピューティングや Big Data をはじめとする様々なエリアでは、数多くの Java をプログラミング言語とした API やフレームワークがオープンソースとして提供されてきており、これらの Java コードを ETL ジョブ内で利用したいという要求はますます高まってきています。Java Integration ステージは Java コードを ETL ジョブに組み込むことを可能にしたステージで、IBM InfoSphere Information Server バージョン 9.1 の新機能としてリリースされました。

Java コード開発者は、Java Integration ステージが提供する API を利用して、Java コード (以下、ユーザコード) を作成、コンパイルし、それを ETL ジョブからアクセス可能なファイルシステム上に配置します。ETL ジョブ開発者は ETL ジョブ中に Java Integration ステージを配置し、Java コード開発者が作成したコードをクラスパスに追加します。

もっとも簡単なサンプルコードをリスト 1 に示します。このコードは、「ディレクター・クライアント」で表示できるジョブ・ログにレコードの列値を出力する単純な Peek ステージ実装を示しています。ここでは単一の入力リンクを想定しています。Java Integration ステージで呼び出し可能なクラスにするために、Java Integration ステージ API で提供されている Processor クラス (com.ibm.is.cc.javastage.api.Processor) を継承したクラスを作成します。

リスト 1. Java Integration ステージ - API サンプル
package samples;

import com.ibm.is.cc.javastage.api.*;

public class SimplePeek extends Processor
{
  private InputLink m_inputLink;

  public boolean validateConfiguration(
    Configuration configuration, 
  boolean isRuntime)throws Exception
  {
    if (configuration.getInputLinkCount() != 1)
    {
      // this sample code assumes stage has 1 input link.
      return false;
    }
    
    m_inputLink = configuration.getInputLink(0);
     
    return true;   
  }

  public void process() throws Exception
  {
    do
    {
      InputRecord inputRecord = m_inputLink.readRecord();
      if (inputRecord == null)
      { 
         // No more input. Your code must return from process() method.
         break;
      }

      for (int i = 0; i < m_inputLink.getColumnCount(); i++) 
      { 
         Object value = inputRecord.getValue(i);
         Logger.information(value.toString());
      }
    } 
    while (true);
  }
}

Information Server パラレルエンジンにおける Java VM

一般に、Java コードをデバッグする際には、そのコードがどのような環境で動くかを知っておくのは非常に重要です。

Java Integration ステージは、DataStage で作成されたパラレルジョブで利用可能で、その実行はパラレルエンジンにより実行されます。複数の CPU に複数の処理ノードを配置し、実行時の並列性を最適化することが可能です。実行時の並列性を最適化することは通常は簡単ではありませんが、パラレルエンジンの場合、ジョブの設計・実装と、ジョブの実行環境の定義が独立しており、ジョブ設計や実装時に何個のノードや CPU で実行されるのかといったことを考慮する必要がありません。そのため効率よくジョブを開発することが可能になります。パラレルエンジンの概要やそのプロセスモデル、動作は IBM InfoSphere Information Server パラレルエンジン 概説: 前編、および後編で非常によく説明されていますので、これらを参照してください。

ユーザコードは Java Virtual Machine (VM) で動きます。Java VM は、Conductor プロセスおよび ETL ジョブ内の Java Integration ステージのインスタンスに対応した各 Player プロセスに一つずつ作成されます。今、仮に ETL ジョブに 1 つの Java Integration ステージを配置して、それを 2 ノード構成で動かしたとします。Java Integration ステージの構成で、Node map constraint なし、Execution mode が Parallel の場合、この ETL ジョブ実行時には合計 3 つの Java VM が作成され、それぞれで Java Integration ステージで指定されたユーザコードが動くことになります。パラレルエンジンが提供する APT_EXECUTION_MODE という環境変数で ONE_PROCESS を指定することにより作成される Java VM は 1 つとなりますが、それ以外は実行時に作成される Java VM を思い描いてデバッグを行うことになります。

以下、2 つのデバッグ方法を説明します。

デバッグログの出力

コードをデバッグするにあたり、デバッグ目的のログメッセージの出力やトレースログを残すことは開発者が常にやりたいことの 1 つでしょう。ここでは Java Integration ステージ API で提供されているログ機能の簡単な使い方を説明します。

Java Integration スレージ API では、Logger クラス (com.ibm.is.cc.javastage.api.Logger) が用意されています。これを使用することで「ディレクター・クライアント」で表示できるジョブ・ログにログメッセージを出力することができます。ログメッセージには「致命的なもの」、「警告」、「情報」および「デバッグ」の 4 つのレベルがあり、出力するメッセージの致命度や用途に応じて、各レベルに対応した Logger クラスのメソッドを呼び出します。Logger.debug(String message) は、デバッグ目的のメッセージを出力するためのもので、デバッグ時に JAVASTAGE_API_DEBUG という環境変数に 1 という値を設定することで出力されます。上記の SimplePeek にリスト 2 に示すようなコンストラクタを追加して、そこでデバッグメッセージを出力してみます。

リスト 2. Logger.debug() を用いたデバッグログの出力方法の例
public SimplePeek()
{
   super();
   Logger.debug(“This is debug message from my code.”);
}

ETL ジョブを実行すると、以下のようなメッセージがジョブ・ログに出力され、「ディレクター・クライアント」で確認することができます (リスト 3)。

リスト 3. デバッグログの出力結果の例
   Item #: 9
   Event ID: 8
   Timestamp: 2015-09-30 09:34:38
   Type: Info
   User Name: IS11310WIN64EN|dsadm
   Message Id: IIS-CONN-JAVA-00011
   Message: SimplePeek: This is debug message from my code.
     :
     :
   Item #: 12
   Event ID: 11
   Timestamp: 2015-09-30 09:34:39
   Type: Info
   User Name: IS11310WIN64EN|dsadm
   Message Id: IIS-CONN-JAVA-00011
   Message: SimplePeek,1: This is debug message from my code.

   Item #: 13
   Event ID: 12
   Timestamp: 2015-09-30 09:34:40
   Type: Info
   User Name: IS11310WIN64EN|dsadm
   Message Id: IIS-CONN-JAVA-00011
   Message: SimplePeek,0: This is debug message from my code.

   :
   :

上記ログは、2 ノードで実行したため、Conductor プロセスと 2 つの Player プロセスでそれぞれ Java VM が作成され、その上で SimplePeek クラスが動いていることがわかります。Conductor プロセスのログメッセージには ETL ジョブ内でのステージ名が、Player プロセスのログメッセージにはステージ名とノード番号が出力されます。これにより、ログメッセージがどのプロセスのユーザコードから出力されたか判定できます。

Eclipse リモートデバッガを用いたデバッグ

デバッグログの出力から大局的にコードの挙動を観測し、その入出力データのトレースを確認することによりバグを発見できることは多々ありますが、より複雑で発見が難しい問題にはデバッガーの利用が非常に有効です。ここではパラレルエンジンが作成する Java VM にリモードデバッガを接続し、その上で動くユーザコードをデバッグする方法を説明します。

Java Integration ステージのユーザコードのデバッグは、他の Java アプリケーションのリモートデバッグと大きな違いはありません。デバッガオプションを指定して Java VM を起動し、Eclipse などの開発ツールからその Java VM にリモート接続を行いデバッグします。

次に、Eclipse を用いたデバッグ手順について説明します。本稿ではデバッガに Eclipse を使用していますが、Java Debug Wire Protocol (JDWP) での接続が可能であるデバッガであれば同様のことができます。

Eclipse プロジェクトの作成

Eclipse を起動し、File > New > Project で、「Java プロジェクト」を作成し、デバッグ対象のユーザコードのソースコードをインポートします。

Java VM オプションの指定

Java Integration ステージのプロパティーには、Conductor および Player プロセスにおける Java VM の起動オプションを指定するプロパティー「Optional JVM Option」があります。このプロパティーに以下に示すようなデバッガオプションを指定します (図 1)。本稿ではデバッガの接続ポート番号に 8000 番のポートを使用します。

-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000, suspend=y
図 1. Java Integration ステージのエディター画面

ETL ジョブの保存と実行

前述のデバッガオプションを指定し、ETL ジョブを保存し、これを実行します。suspend=y を指定することにより、Conductor プロセスの Java VM 起動の最初でデバッガからの接続を待ちます。

Eclipse デバッガによる接続

接続手順を以下に示します。

  1. Run > Debug Configurations… でデバッグの構成画面を起動します。最初に左側のビューで Remote Java Application エントリーを選択し、次に New をクリックします。そうするとリモート起動用の新しい構成が作成され、Connect と Source, Common という 3 つのタブが表示されます。Connect のタブの Connection Type には Standard (Socket Attach) を、ホスト名には ETL ジョブが動く DataStage エンジンのホスト名、ポート番号は Java VM のデバッガオプションで指定したものを入力します (図 2)。
  2. Debug ボタンをクリックします。Debug パースペクティブに遷移し、Java VM に接続されます。
  3. Debug ビューのツールバーで Resume ボタンをクリックして、次の Java VM の起動に進みます。
図 2. リモートデバッガの構成

前述のようにパラレルエンジンでは、Conductor プロセスに 1 つ、Player プロセス毎に 1 つずつの Java VM が起動されますので、上記、1-3 の手順を起動される Java VM の個数分、繰り返し、Java VM を休止状態から復帰させます。途中、ブレークポイントを設定したい場合は、ここで行います。すべての Java VM とデバッガが接続されると、ETL ジョブが動きはじめます。図 3 は、デバッガが Conductor プロセスおよび 2 つの Player プロセスの Java VM と接続している様子を示します。

図 3. Java Integration スレージの Java VM とデバッガの接続

あとは、Eclipse を用いた Java アプリケーションのリモートデバッグと同じです。ブレークポイントを設定すれば、そこでユーザコードの実行は止まりますし、変数値を見ることができます。図 4 は、前段のステージから送られてくるレコードの内容を確認している例です。Java Integration ステージでは、Record クラス (com.ibm.is.cc.javastage.api.Record) のプライベートメンバー変数 m_dataItems にレコードの Raw データが含まれています。

図 4. 入力レコードに含まれる列データの確認

デバッグしていると、今、どのプロセス上で動くユーザコードをデバッグしているかわからなくなる時があります。そのために、リスト 4 に示すように、Configuration クラス (com.ibm.is.cc.javastage.api.Configuration) のインスタンスからノード番号を取得し、メンバー変数に代入しておくことで、デバッガからこの値を確認し、どのプロセス上のものかを知ることができます。

リスト 4. ノード番号の取得例
private int _nodeNumber = -1;

   public boolean validateConfiguration(
                   Configuration configuration, 
                         boolean isRuntime) throws Exception
   {
      _nodeNumber = configurations.getNodeNumber();
   
      :

トラブルシューティング

ユーザコードの実装に起因するエラーに加え、Java Integration ステージの構成に起因するエラーが発生することがあります。こうしたエラーは、Java Integration ステージのプロパティーまたは構成の値を調整すれば解決できる場合があります。Java Integration ステージのトラブルシューティング例は、InfoSphere Information Server Knowledge Center に記述があります。

OutOfMemoryError 等の Java VM エラーにより実行継続不能となった場合は、ETL ジョブが存在している DataStage のプロジェクトのディレクトリに javacore ファイルをはじめとするダンプ・ファイルが作成されますので、ここから原因を特定することができます。

まとめ

本稿では、IBM InfoSphere Information Server バージョン 9.1 から提供されている Java Integration ステージのユーザコードのデバッグ方法として、Java Integration ステージ API で提供されている Logger クラスを用いたログメッセージの出力によるものとリモートデバッガを使用した例を紹介しました。

Java Integration ステージは IBM InfoSphere Connectivity SDK でも用いられ、本 SDK を使用することにより、DataStage で利用可能なカスタムステージを作成することが可能となります。本稿で紹介したデバッグ方法は、このカスタムステージの開発にも適用可能です。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Information Management, Java technology
ArticleID=1017370
ArticleTitle=Java Integration ステージにおけるユーザコードのデバッグ
publish-date=10142015