4.5. 国際化と現地語化

4.5.1. はじめに

4.5.1.1. 国際化

国際化とは、技術的な変更を行わずに異なる言語や地域に対してソフトウェアを適合させるソフトウェア設計のプロセスのことです。

4.5.1.2. 多言語化

多言語化とは、特定の地域や言語に対してロケール固有のコンポーネントやテキストの翻訳を追加することで、国際化されたソフトウェアを適合させるプロセスのことです。

4.5.2. JBoss Logging Tools の国際化および現地語化

JBoss Logging Tools は、ログメッセージ、例外メッセージ、および汎用文字列の国際化や現地語化のサポートを提供する Java API です。JBoss Logging Tools は翻訳のメカニズムを提供するだけでなく、各ログメッセージに対して一意な識別子のサポートも提供します。

国際化されたメッセージと例外は、org.jboss.logging.annotations アノテーションが付けられたインターフェース内でメソッド定義として作成されます。インターフェースを実装する必要はありません。JBoss Logging Tools がコンパイル時にインターフェースを実装します。定義すると、これらのメソッドを使用してコードでメッセージをログに記録したり、例外オブジェクトを取得したりできます。

JBoss Logging Tools によって作成される国際化されたロギングインターフェースや例外インターフェースは、特定の言語や地域に対する翻訳が含まれる各バンドルのプロパティーファイルを作成して現地語化されます。JBoss Logging Tools は、トランスレーターが編集できる各バンドル対してテンプレートプロパティーファイルを生成できます。

JBoss Logging Tools は、プロジェクトの対象翻訳プロパティーファイルごとに各バンドルの実装を作成します。必要なのはバンドルに定義されているメソッドを使用することのみで、JBoss Logging Tools は現在の地域設定に対して正しい実装が呼び出されるようにします。

メッセージ ID とプロジェクトコードは各ログメッセージの前に付けられる一意の識別子です。この一意の識別子をドキュメントで使用すると、ログメッセージの情報を簡単に検索することができます。適切なドキュメントでは、メッセージが書かれた言語に関係なく、ログメッセージの意味を識別子から判断できます。

JBoss Logging Tools には次の機能のサポートが含まれます。

MessageLogger
org.jboss.logging.annotations パッケージ内のこのインターフェースは、国際化されたログメッセージを定義するために使用されます。メッセージロガーインターフェースは @MessageLogger アノテーションが付けられます。
MessageBundle
このインターフェースは、翻訳可能な汎用メッセージと国際化されたメッセージが含まれる例外オブジェクトを定義するために使用できます。メッセージバンドルは、ログメッセージの作成には使用されません。メッセージバンドルインターフェースは、@MessageBundle アノテーションが付けられます。
国際化されたログメッセージ

これらのログメッセージは、MessageLogger のメソッドを定義して作成されます。メソッドは @LogMessage アノテーションと @Message アノテーションを付け、@Message の値属性を使用してログメッセージを指定する必要があります。国際化されたログメッセージはプロパティーファイルで翻訳を提供することによりローカライズされます。

JBoss Logging Tools はコンパイル時に各翻訳に必要なロギングクラスを生成し、ランタイム時に現ロケールに対して適切なメソッドを呼び出します。

国際化された例外
国際化された例外は、MessageBundle で定義されたメソッドから返された例外オブジェクトです。これらのメッセージバンドルは、デフォルトの例外メッセージを定義するためにアノテーションを付けることができます。デフォルトのメッセージは、現在のロケールと一致するプロパティーファイルに翻訳がある場合にその翻訳に置き換えられます。国際化された例外にも、プロジェクトコードとメッセージ ID を割り当てることができます。
国際化されたメッセージ
国際化されたメッセージは、MessageBundle で定義されたメソッドから返された文字列です。Java String オブジェクトを返すメッセージバンドルメソッドは、その文字列のデフォルトの内容 (メッセージと呼ばれます) を定義するためにアノテーションを付けることができます。デフォルトのメッセージは、現在のロケールと一致するプロパティーファイルに翻訳がある場合にその翻訳に置き換えられます。
翻訳プロパティーファイル
翻訳プロパティーファイルは、1 つのロケール、国、バリアントに対する 1 つのインターフェースのメッセージの翻訳が含まれる Java プロパティーファイルです。翻訳プロパティーファイルは、メッセージを返すクラスを生成するために JBoss Logging Tools によって使用されます。
JBoss Logging Tools のプロジェクトコード

プロジェクトコードはメッセージのグループを識別する文字列です。プロジェクトコードは各ログメッセージの最初に表示され、メッセージ ID の前に付けられます。プロジェクトコードは @MessageLogger アノテーションの projectCode 属性で定義されます。

注記

新しいログメッセージプロジェクトコード接頭辞の完全なリストは、JBoss EAP 7.2 で使用されているプロジェクトコードを参照してください。

JBoss Logging Tools のメッセージ ID
メッセージ ID はプロジェクトコードと組み合わせてログメッセージを一意に識別する数字です。メッセージ ID は各ログメッセージの最初に表示され、メッセージのプロジェクトコードの後に付けられます。メッセージ ID は @Message アノテーションの ID 属性で定義されます。

JBoss EAP に同梱される logging-tools クイックスタートは、JBoss Logging Tools の多くの機能の例を提供する単純な Maven プロジェクトです。以降のコード例は、logging-tools クイックスタートから取得されました。

4.5.3. 国際化されたロガー、メッセージ、例外の作成

4.5.3.1. 国際化されたログメッセージの作成

JBoss Logging Tools を使用して MessageLogger インターフェースを作成することにより、国際化されたログメッセージを作成できます。

注記

ここでは、ログメッセージのすべてのオプション機能または国際化について説明しません。

  1. JBoss EAP Maven レポジトリーを使用するよう Maven を設定します (まだそのように設定していない場合)。

    詳細は、「Maven 設定を使用した JBoss EAP Maven リポジトリーの設定」を参照してください。

  2. JBoss Logging Tools を使用するようプロジェクトの pom.xml ファイルを設定します。

    詳細は、「JBoss Logging Tools の Maven 設定」を参照してください。

  3. ログメッセージ定義を含めるために Java インターフェースをプロジェクトに追加して、メッセージロガーインターフェースを作成します。

    定義するログメッセージの内容がわかるようインターフェースに名前を付けます。ログメッセージインターフェースの要件は次のとおりです。

    • @org.jboss.logging.annotations.MessageLogger アノテーションを付ける必要があります。
    • オプションで、org.jboss.logging.BasicLogger を拡張できます。
    • インターフェースと同じ型のメッセージロガーであるフィールドをインターフェースで定義する必要があります。これは、@org.jboss.logging.LoggergetMessageLogger() を使用して行います。

      例: メッセージロガーの作成

      package com.company.accounts.loggers;
      
      import org.jboss.logging.BasicLogger;
      import org.jboss.logging.Logger;
      import org.jboss.logging.annotations.MessageLogger;
      
      @MessageLogger(projectCode="")
      interface AccountsLogger extends BasicLogger {
         AccountsLogger LOGGER = Logger.getMessageLogger(
               AccountsLogger.class,
               AccountsLogger.class.getPackage().getName() );
      }

  4. 各ログメッセージのインターフェースにメソッド定義を追加します。

    ログメッセージの各メソッドにその内容を表す名前を付けます。各メソッドの要件は次のとおりです。

    • メソッドは void を返す必要があります。
    • @org.jboss.logging.annotation.LogMessage アノテーションを付ける必要があります。
    • @org.jboss.logging.annotations.Message アノテーションを付ける必要があります。
    • デフォルトのログレベルは INFO です。
    • @org.jboss.logging.annotations.Message の値属性にはデフォルトのログインメッセージが含まれます。このメッセージは翻訳がない場合に使用されます。

      @LogMessage
      @Message(value = "Customer query failed, Database not available.")
      void customerQueryFailDBClosed();
  5. メッセージをログに記録する必要があるコードで呼び出しをインターフェースメソッドに追加してメソッドを呼び出します。

    インターフェースの実装を作成する必要はありません。 これは、プロジェクトがコンパイルされる時にアノテーションプロセッサーにより行われます。

    AccountsLogger.LOGGER.customerQueryFailDBClosed();

    カスタムのロガーは BasicLogger からサブクラス化されるため、BasicLogger のロギングメソッドを使用することもできます。国際化されていないメッセージをログに記録するために他のロガーを作成する必要はありません。

    AccountsLogger.LOGGER.error("Invalid query syntax.");
  6. プロジェクトで、現地語化できる 1 つ以上の国際化されたロガーがサポートされるようになります。
注記

JBoss EAP に同梱される logging-tools クイックスタートは、JBoss Logging Tools の使用例を提供する単純な Maven プロジェクトです。

4.5.3.2. 国際化されたメッセージの作成と使用

この手順では、国際化された例外を作成および使用する方法を示します。

注記

本項では、これらのメッセージの現地語化に関するすべてのオプション機能またはプロセスについて説明しません。

  1. JBoss EAP Maven レポジトリーを使用するよう Maven を設定します (まだそのように設定していない場合)。詳細は、「Maven 設定を使用した JBoss EAP Maven リポジトリーの設定」を参照してください。
  2. JBoss Logging Tools を使用するようプロジェクトの pom.xml ファイルを設定します。詳細は、「JBoss Logging Tools の Maven 設定」を参照してください。
  3. 例外のインターフェースを作成します。JBoss Logging Tools はインターフェースで国際化されたメッセージを定義します。含まれるメッセージのインターフェースにその内容を表す名前を付けます。インターフェースの要件は以下のとおりです。

    • public として宣言する必要があります。
    • @org.jboss.logging.annotations.MessageBundle アノテーションを付ける必要があります。
    • インターフェースと同じ型のメッセージバンドルであるフィールドをインターフェースが定義する必要があります。

      例: MessageBundle インターフェースの作成

      @MessageBundle(projectCode="")
      public interface GreetingMessageBundle {
         GreetingMessageBundle MESSAGES = Messages.getBundle(GreetingMessageBundle.class);
      }

      注記

      Messages.getBundle(GreetingMessagesBundle.class) を呼び出すのは Messages.getBundle(GreetingMessagesBundle.class, Locale.getDefault()) を呼び出すのと同等です。

      Locale.getDefault() は、Java Virtual Machine のこのインスタンスのデフォルトロケールに対する現在の値を取得します。起動時に、ホストの環境に基づいて Java Virtual Machine によりデフォルトのロケールが設定されます。これは、ロケールが明示的に指定されていない場合に、ロケールに関連する多くのメソッドによって使用されます。これは、setDefault メソッドで変更できます。

      詳細は、JBoss EAP『設定ガイド』の「サーバーのデフォルトロケールの設定」を参照してください。

  4. 各メッセージのインターフェースにメソッド定義を追加します。メッセージに対する各メソッドにその内容を表す名前を付けます。各メソッドの要件は次のとおりです。

    • String のオブジェクトを返す必要があります。
    • @org.jboss.logging.annotations.Message アノテーションを付ける必要があります。
    • デフォルトメッセージに @org.jboss.logging.annotations.Message の値属性を設定する必要があります。このメッセージは翻訳がない場合に使用されます。

      @Message(value = "Hello world.")
      String helloworldString();
  5. メッセージを取得する必要があるアプリケーションでインターフェースメソッドを呼び出します。

    System.out.println(helloworldString());

プロジェクトで、現地語化できる国際化されたメッセージ文字列がサポートされるようになります。

注記

使用できる完全な例は、JBoss EAP に同梱される logging-tools クイックスタートを参照してください。

4.5.3.3. 国際化された例外の作成

JBoss Logging Tools を使用して、国際化された例外を作成および使用できます。

以下の手順では、Red Hat CodeReady Studio または Maven のいずれかを使用してビルドされた既存のソフトウェアプロジェクトに、国際化された例外を追加することを前提としています。

注記

ここでは、これらの例外のすべてのオプション機能または国際化のプロセスについて説明しません。

  1. JBoss Logging Tools を使用するようプロジェクトの pom.xml ファイルを設定します。詳細は、「JBoss Logging Tools の Maven 設定」を参照してください。
  2. 例外のインターフェースを作成します。JBoss Logging Tools はインターフェースで国際化されたメッセージを定義します。各インターフェースに定義する例外を表す名前を付けます。インターフェースの要件は以下のとおりです。

    • public として宣言する必要があります。
    • @MessageBundle アノテーションを付ける必要があります。
    • インターフェースと同じ型のメッセージバンドルであるフィールドをインターフェースが定義する必要があります。

      例: ExceptionBundle インターフェースの作成

      @MessageBundle(projectCode="")
      public interface ExceptionBundle {
         ExceptionBundle EXCEPTIONS = Messages.getBundle(ExceptionBundle.class);
      }

  3. 各例外のインターフェースにメソッド定義を追加します。例外に対する各メソッドにその内容を表す名前を付けます。各メソッドの要件は次のとおりです。

    • Exception オブジェクトまたは Exception のサブタイプを返す必要があります。
    • @org.jboss.logging.annotations.Message アノテーションを付ける必要があります。
    • デフォルトの例外メッセージに @org.jboss.logging.annotations.Message の値属性を設定する必要があります。このメッセージは翻訳がない場合に使用されます。
    • メッセージ文字列の他にパラメーターを必要とするコンストラクターが返される例外にある場合は、@Param アノテーションを使用してこれらのパラメーターをメソッド定義に提供する必要があります。パラメーターは、例外のコンストラクターと同じ型および順番である必要があります。

      @Message(value = "The config file could not be opened.")
      IOException configFileAccessError();
      
      @Message(id = 13230, value = "Date string '%s' was invalid.")
      ParseException dateWasInvalid(String dateString, @Param int errorOffset);
  4. 例外を取得する必要があるコードでインターフェースメソッドを呼び出します。メソッドによって例外は発生されず、発生できるな例外オブジェクトがメソッドによって返されます。

    try {
       propsInFile=new File(configname);
       props.load(new FileInputStream(propsInFile));
    }
    catch(IOException ioex) {
      //in case props file does not exist
       throw ExceptionBundle.EXCEPTIONS.configFileAccessError();
    }

プロジェクトで、現地語化できる国際化された例外がサポートされるようになります。

注記

使用できる完全な例は、JBoss EAP に同梱される logging-tools クイックスタートを参照してください。

4.5.4. 国際化されたロガー、メッセージ、例外の現地語化

4.5.4.1. Maven での新しい翻訳プロパティーファイルの作成

Maven で構築されたプロジェクトでは、含まれる MessageLoggerMessageBundle それぞれに対して空の翻訳プロパティーファイルを生成できます。これらのファイルは新しい翻訳プロパティーファイルとして使用することができます。

新しい翻訳プロパティーファイルを生成するよう Maven プロジェクトを設定する手順は次のとおりです。

要件

  • 作業用の Maven プロジェクトがすでに存在している必要があります。
  • JBoss Logging Tools に対してプロジェクトが設定されていなければなりません。
  • 国際化されたログメッセージや例外を定義する 1 つ以上のインターフェースがプロジェクトに含まれていなければなりません。

翻訳プロパティーファイルの生成

  1. -AgenereatedTranslationFilePath コンパイラー引数を Maven コンパイラープラグイン設定に追加し、新しいファイルが作成されるパスを割り当てます。

    この設定では、Maven プロジェクトの target/generated-translation-files ディレクトリーに新しいファイルが作成されます。

    例: 翻訳ファイルパスの定義

    <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-compiler-plugin</artifactId>
       <version>2.3.2</version>
       <configuration>
          <source>1.6</source>
          <target>1.6</target>
          <compilerArgument>
          -AgeneratedTranslationFilesPath=${project.basedir}/target/generated-translation-files
          </compilerArgument>
          <showDeprecation>true</showDeprecation>
       </configuration>
    </plugin>

  2. Maven を使用してプロジェクトをビルドします。

    $ mvn compile

    @MessageBundle または @MessageLogger アノテーションが付けられた各インターフェースに対して 1 つのプロパティーファイルが作成されます。

    • 各インターフェースが宣言された Java パッケージに対応するサブディレクトリーに新しいファイルが作成されます。
    • 新しい各ファイルには、以下のパターンで名前が付けられます。 ここで、INTERFACE_NAME はファイルを生成するために使用するインターフェースの名前です。

      INTERFACE_NAME.i18n_locale_COUNTRY_VARIANT.properties

生成されたファイルは新しい翻訳の基礎としてプロジェクトにコピーできます。

注記

使用できる完全な例は、JBoss EAP に同梱される logging-tools クイックスタートを参照してください。

4.5.4.2. 国際化されたロガー、例外、またはメッセージの翻訳

プロパティーファイルは、JBoss Logging Tools を使用してインターフェースで定義されたロギングおよび例外メッセージの翻訳を提供します。

次の手順は、翻訳プロパティーファイルの作成方法と使用方法を示しています。 この手順では、国際化された例外またはログメッセージに対して 1 つ以上のインターフェースがすでに定義されているプロジェクトが存在することを前提にしています。

要件

  • 作業用の Maven プロジェクトがすでに存在している必要があります。
  • JBoss Logging Tools に対してプロジェクトが設定されていなければなりません。
  • 国際化されたログメッセージや例外を定義する 1 つ以上のインターフェースがプロジェクトに含まれていなければなりません。
  • テンプレート翻訳プロパティーファイルを生成するようプロジェクトが設定されている必要があります。

国際化されたロガー、例外、またはメッセージの翻訳

  1. 以下のコマンドを実行して、テンプレート翻訳プロパティーファイルを作成します。

    $ mvn compile
  2. 翻訳したいインターフェースのテンプレートを、テンプレートが作成されたディレクトリーからプロジェクトの src/main/resources ディレクトリーにコピーします。プロパティーファイルは翻訳するインターフェースと同じパッケージに存在する必要があります。
  3. コピーしたテンプレートファイルの名前を変更して、そのテンプレートに含まれる言語を指定します。例: GreeterLogger .i18n_fr_FR.properties
  4. 新しい翻訳プロパティーファイルの内容を編集し、適切な翻訳が含まれるようにします。

    # Level: Logger.Level.INFO
    # Message: Hello message sent.
    logHelloMessageSent=Bonjour message envoyé.
  5. テンプレートをコピーし、バンドルの各翻訳のために変更するプロセスを繰り返します。

プロジェクトに 1 つ以上のメッセージバンドルまたはロガーバンドルに対する翻訳が含まれるようになります。プロジェクトをビルドすると、提供された翻訳が含まれるログメッセージに対して適切なクラスが生成されます。JBoss Logging Tools は、アプリケーションサーバーの現在のロケールに合わせて適切なクラスを自動的に使用するため、明示的にメソッドを呼び出したり、特定言語のパラメーターを提供したりする必要はありません。

生成されたクラスのソースコードは target/generated-sources/annotations/ で確認できます。

4.5.5. 国際化されたログメッセージのカスタマイズ

4.5.5.1. ログメッセージへのメッセージ ID とプロジェクトコードの追加

この手順は、メッセージ ID とプロジェクトコードを JBoss Logging Tools を使用して作成された国際化済みログメッセージへ追加する方法を示しています。ログメッセージがログで表示されるようにするには、プロジェクトコードとメッセージ ID の両方が必要です。メッセージにプロジェクトコードとメッセージ ID の両方がない場合は、どちらも表示されません。

要件

  1. 国際化されたログメッセージが含まれるプロジェクトが存在する必要があります。「国際化されたログメッセージの作成」を参照してください。
  2. 使用するプロジェクトコードを知っている必要があります。プロジェクトコードを 1 つ使用することも、各インターフェースに異なる複数のコードを定義することも可能です。

ログメッセージへのメッセージ ID とプロジェクトコードの追加

  1. カスタムのロガーインターフェースに付けられる @MessageLogger アノテーションの projectCode 属性を使用してプロジェクトコードを指定します。インターフェースに定義されるすべてのメッセージがこのプロジェクトコードを使用します。

    @MessageLogger(projectCode="ACCNTS")
    interface AccountsLogger extends BasicLogger {
    
    }
  2. メッセージを定義するメソッドに付けられる @Message アノテーションの id 属性を使用して、各メッセージのメッセージ ID を指定します。

    @LogMessage
    @Message(id=43, value = "Customer query failed, Database not available.")  void customerQueryFailDBClosed();
  3. メッセージ ID とプロジェクトコードの両方が関連付けられたログメッセージでは、メッセージ ID とプロジェクトコードがログに記録されたメッセージの前に付けられます。

    10:55:50,638 INFO  [com.company.accounts.ejb] (MSC service thread 1-4) ACCNTS000043: Customer query failed, Database not available.

4.5.5.2. メッセージのログレベル設定

JBoss Logging Tools のインターフェースによって定義されるメッセージのデフォルトのログレベルは INFO です。ロギングメソッドに付けられた @LogMessage アノテーションの level 属性を用いて異なるログレベルを指定することが可能です。異なるログレベルを指定するには、以下の手順を実行します。

  1. ログメッセージメソッド定義の @LogMessage アノテーションに level 属性を追加します。
  2. level 属性を使用してこのメッセージにログレベルを割り当てます。level の有効値は org.jboss.logging.Logger.Level で定義された DEBUGERRORFATALINFOTRACE、および WARN の 6 つの列挙定数です。

    import org.jboss.logging.Logger.Level;
    
    @LogMessage(level=Level.ERROR)
    @Message(value = "Customer query failed, Database not available.")
    void customerQueryFailDBClosed();

上記の例のロギングメソッドを呼び出すと、ERROR レベルのログメッセージが作成されます。

10:55:50,638 ERROR  [com.company.app.Main] (MSC service thread 1-4)
 Customer query failed, Database not available.

4.5.5.3. パラメーターによるログメッセージのカスタマイズ

カスタムのログインメソッドはパラメーターを定義できます。これらのパラメーターを使用してログメッセージに表示される追加情報を渡すことが可能です。ログメッセージでパラメーターが表示される場所は、明示的なインデクシングか通常のインデクシングを使用してメッセージ自体に指定されます。

パラメーターによるログメッセージのカスタマイズ

  1. すべての型のパラメーターをメソッド定義に追加します。型に関係なくパラメーターの String 表現がメッセージに表示されます。
  2. ログメッセージにパラメーター参照を追加します。参照は明示的なインデックスまたは通常のインデックスを使用できます。

    • 通常のインデックスを使用するには、各パラメーターを表示したいメッセージ文字列に %s 文字を挿入します。%s の最初のインスタンスにより最初のパラメーターが挿入され、2 番目のインスタンスにより 2 番目のパラメーターが挿入されます。
    • 明示的なインデックスを使用するには、文字 %#$s をメッセージに挿入します。ここで、# は表示したいパラメーターの数を示します。

明示的なインデックスを使用すると、メッセージのパラメーター参照の順番がメソッドで定義される順番とは異なるようになります。これは、異なるパラメーターの順番が必要になる可能性がある翻訳済みメッセージで重要になります。

重要

指定されたメッセージでは、パラメーターの数とパラメーターへの参照の数が同じでなければなりません。同じでないとコードがコンパイルされません。@Cause アノテーションが付けられたパラメーターはパラメーターの数には含まれません。

以下に、通常のインデックスを使用したメッセージパラメーターの例を示します。

@LogMessage(level=Logger.Level.DEBUG)
@Message(id=2, value="Customer query failed, customerid:%s, user:%s")
void customerLookupFailed(Long customerid, String username);

以下に、明示的なインデックスを使用したメッセージパラメーターの例を示します。

@LogMessage(level=Logger.Level.DEBUG)
@Message(id=2, value="Customer query failed, user:%2$s, customerid:%1$s")
void customerLookupFailed(Long customerid, String username);

4.5.5.4. 例外をログメッセージの原因として指定

JBoss Logging Tools では、カスタムログインメソッドのパラメーターの 1 つをメッセージの原因として定義することができます。定義するには、このパラメーターを Throwable 型またはいずれかのサブクラスにし、@Cause アノテーションを付ける必要があります。このパラメーターは、他のパラメーターのようにログメッセージで参照することはできず、ログメッセージの後に表示されます。

次の手順は、@Cause パラメーターを使用して「原因となる」例外を示し、ロギングメソッドを更新する方法を表しています。この機能に追加したい国際化されたロギングメッセージがすでに作成されていることを前提とします。

例外をログメッセージの原因として指定

  1. Throwable 型のパラメーターまたはサブクラスをメソッドに追加します。

    @LogMessage
    @Message(id=404, value="Loading configuration failed. Config file:%s")
    void loadConfigFailed(Exception ex, File file);
  2. パラメーターに @Cause アノテーションを追加します。

    import org.jboss.logging.annotations.Cause
    
    @LogMessage
    @Message(value = "Loading configuration failed. Config file: %s")
    void loadConfigFailed(@Cause Exception ex, File file);
  3. メソッドを呼び出します。コードでメソッドが呼び出されると、正しい型のオブジェクトが渡され、ログメッセージの後に表示されます。

    try
    {
       confFile=new File(filename);
       props.load(new FileInputStream(confFile));
    }
    catch(Exception ex) //in case properties file cannot be read
    {
         ConfigLogger.LOGGER.loadConfigFailed(ex, filename);
    }

コードによって FileNotFoundException 型の例外が発生した場合、上記コード例の出力は次のようになります。

10:50:14,675 INFO [com.company.app.Main] (MSC service thread 1-3) Loading configuration failed. Config file: customised.properties
java.io.FileNotFoundException: customised.properties (No such file or directory)
   at java.io.FileInputStream.open(Native Method)
   at java.io.FileInputStream.<init>(FileInputStream.java:120)
   at com.company.app.demo.Main.openCustomProperties(Main.java:70)
   at com.company.app.Main.go(Main.java:53)
   at com.company.app.Main.main(Main.java:43)

4.5.6. 国際化された例外のカスタマイズ

4.5.6.1. メッセージ ID およびプロジェクトコードの例外メッセージへの追加

メッセージ ID およびプロジェクトコードは、国際化された例外によって表示される各メッセージの前に付けられる一意の識別子です。これらの識別コードにより、アプリケーションですべての例外メッセージの参照を作成できます。これにより、習得していない言語で書かれた例外メッセージの意味を検索できます。

以下の手順は、JBoss Logging Tools を使用して作成された国際化済み例外メッセージにメッセージ ID とプロジェクトコードを追加する方法を示しています。

要件

  1. 国際化された例外が含まれるプロジェクトが存在する必要があります。詳細は、「国際化された例外の作成」を参照してください。
  2. 使用するプロジェクトコードを知っている必要があります。プロジェクトコードを 1 つ使用することも、各インターフェースに異なる複数のコードを定義することも可能です。

メッセージ ID およびプロジェクトコードの例外メッセージへの追加

  1. 例外バンドルインターフェースに付けられる @MessageBundle アノテーションの projectCode 属性を使用して、プロジェクトコードを指定します。インターフェースに定義されるすべてのメッセージがこのプロジェクトコードを使用します。

    @MessageBundle(projectCode="ACCTS")
    interface ExceptionBundle
    {
       ExceptionBundle EXCEPTIONS = Messages.getBundle(ExceptionBundle.class);
    }
  2. 例外を定義するメソッドに付けられる @Message アノテーションの id 属性を使用して、各例外に対してメッセージ ID を指定します。

    @Message(id=143, value = "The config file could not be opened.")
    IOException configFileAccessError();
重要

プロジェクトコードとメッセージ ID を両方持つメッセージでは、メッセージの前にプロジェクトコードとメッセージ ID が表示されます。プロジェクトコードとメッセージ ID の両方がない場合は、どちらも表示されません。

例: 国際化された例外

この例外バンドルインターフェースの例では、「ACCTS」のプロジェクトコードを使用しています。ID が「143」である例外メソッドが 1 つ含まれています。

@MessageBundle(projectCode="ACCTS")
interface ExceptionBundle
{
    ExceptionBundle EXCEPTIONS = Messages.getBundle(ExceptionBundle.class);

    @Message(id=143, value = "The config file could not be opened.")
    IOException configFileAccessError();
}

次のコードを使用すると、例外オブジェクトを取得および発生できます。

throw ExceptionBundle.EXCEPTIONS.configFileAccessError();

これにより、次のような例外メッセージが表示されます。

Exception in thread "main" java.io.IOException: ACCTS000143: The config file could not be opened.
at com.company.accounts.Main.openCustomProperties(Main.java:78)
at com.company.accounts.Main.go(Main.java:53)
at com.company.accounts.Main.main(Main.java:43)

4.5.6.2. パラメーターによる例外メッセージのカスタマイズ

例外を定義する例外バンドルメソッドでは、パラメーターを指定して例外メッセージに表示される追加情報を渡すことが可能です。例外メッセージでのパラメーターの正確な位置は、明示的なインデックスまたは通常のインデックスを使用してメッセージ自体に指定されます。

パラメーターによる例外メッセージのカスタマイズ

  1. すべての型のパラメーターをメソッド定義に追加します。型に関係なくパラメーターの String 表現がメッセージに表示されます。
  2. 例外メッセージにパラメーター参照を追加します。参照は明示的なインデックスまたは通常のインデックスを使用できます。

    • 通常のインデックスを使用するには、各パラメーターを表示したいメッセージ文字列に %s 文字を挿入します。%s の最初のインスタンスにより最初のパラメーターが挿入され、2 番目のインスタンスにより 2 番目のパラメーターが挿入されます。
    • 明示的なインデックスを使用するには、文字 %#$s をメッセージに挿入します。ここで、# は表示したいパラメーターの数を示します。

明示的なインデックスを使用すると、メッセージのパラメーター参照の順番がメソッドで定義される順番とは異なるようになります。これは、異なるパラメーターの順番が必要になる可能性がある翻訳済みメッセージで重要になります。

重要

指定されたメッセージでは、パラメーターの数とパラメーターへの参照の数が同じでなければなりません。@Cause アノテーションが付けられたパラメーターはパラメーターの数には含まれません。

例: 通常のインデックスの使用

@Message(id=2, value="Customer query failed, customerid:%s, user:%s")
void customerLookupFailed(Long customerid, String username);

例: 明示的なインデックスの使用

@Message(id=2, value="Customer query failed, user:%2$s, customerid:%1$s")
void customerLookupFailed(Long customerid, String username);

4.5.6.3. 別の例外の原因として 1 つの例外を指定

例外バンドルメソッドより返された例外に対し、他の例外を基礎となる原因として指定することができます。指定するには、パラメーターをメソッドに追加し、パラメーターに @Cause アノテーションを付けます。このパラメーターを使用して原因となる例外を渡します。 このパラメーターを例外メッセージで参照することはできません。

次の手順は、@Cause パラメーターを使用して原因となる例外を示し、例外バンドルよりメソッドを更新する方法を表しています。この機能に追加したい国際化された例外バンドルがすでに作成されていることを前提とします。

  1. Throwable 型のパラメーターまたはサブクラスをメソッドに追加します。

    @Message(id=328, value = "Error calculating: %s.")
    ArithmeticException calculationError(Throwable cause, String msg);
  2. パラメーターに @Cause アノテーションを追加します。

    import org.jboss.logging.annotations.Cause
    
    @Message(id=328, value = "Error calculating: %s.")
    ArithmeticException calculationError(@Cause Throwable cause, String msg);
  3. 例外オブジェクトを取得するため、インターフェースメソッドを呼び出します。catch ブロックから新しい例外を発生させ、キャッチした例外を原因として指定するのが最も一般的なユースケースです。

    try
    {
       ...
    }
    catch(Exception ex)
    {
       throw ExceptionBundle.EXCEPTIONS.calculationError(
                                        ex, "calculating payment due per day");
    }

以下に、例外を別の例外の原因として指定する例を示します。この例外バンドルでは、ArithmeticException 型の例外を返す単一のメソッドを定義します。

@MessageBundle(projectCode = "TPS")
interface CalcExceptionBundle
{
    CalcExceptionBundle EXCEPTIONS = Messages.getBundle(CalcExceptionBundle.class);

    @Message(id=328, value = "Error calculating: %s.")
    ArithmeticException calcError(@Cause Throwable cause, String value);
}

以下は、整数のゼロ除算が行われると例外が発生する操作の例になります。例外がキャッチされ、その最初の例外を原因として使用して新しい例外が作成されます。

int totalDue = 5;
int daysToPay = 0;
int amountPerDay;

try
{
   amountPerDay = totalDue/daysToPay;
}
catch (Exception ex)
{
   throw CalcExceptionBundle.EXCEPTIONS.calcError(ex, "payments per day");
}

以下は、前の例から生成された例外メッセージになります。

Exception in thread "main" java.lang.ArithmeticException: TPS000328: Error calculating: payments per day.
    at com.company.accounts.Main.go(Main.java:58)
    at com.company.accounts.Main.main(Main.java:43)
Caused by: java.lang.ArithmeticException: / by zero
    at com.company.accounts.Main.go(Main.java:54)
    ... 1 more

4.5.7. JBoss Logging Tools のリファレンス

4.5.7.1. JBoss Logging Tools の Maven 設定

以下の手順では、国際化のために JBoss Logging と JBoss Logging Tools を使用するよう Maven プロジェクトを設定します。

  1. JBoss EAP レポジトリーを使用するよう Maven を設定します (まだそのように設定していない場合)。詳細は、「Maven 設定を使用した JBoss EAP Maven リポジトリーの設定」を参照してください。

    pom.xml ファイルの <dependencyManagement> セクションに jboss-eap-javaee8 BOM を含めます。

    <dependencyManagement>
      <dependencies>
        <!-- JBoss distributes a complete set of Java EE APIs including
          a Bill of Materials (BOM). A BOM specifies the versions of a "stack" (or
          a collection) of artifacts. We use this here so that we always get the correct versions of artifacts.
          Here we use the jboss-javaee-7.0 stack (you can
          read this as the JBoss stack of the Java EE APIs). You can actually
          use this stack with any version of JBoss EAP that implements Java EE. -->
        <dependency>
          <groupId>org.jboss.bom</groupId>
           <artifactId>jboss-eap-javaee8</artifactId>
           <version>7.2.0.GA</version>
           <type>pom</type>
           <scope>import</scope>
        </dependency>
      <dependencies>
    <dependencyManagement>
  2. Maven 依存関係をプロジェクトの pom.xml ファイルに追加します。

    1. JBoss Logging フレームワークにアクセスするために jboss-logging 依存関係を追加します。
    2. JBoss Logging Tools を使用する場合は、jboss-logging-processor 依存関係も追加します。

      これら両方の依存関係は、前の手順で追加された JBoss EAP BOM で利用できます。 したがって、各依存関係のスコープ要素は示されているように provided に設定できます。

      <!-- Add the JBoss Logging Tools dependencies -->
      <!-- The jboss-logging API -->
      <dependency>
         <groupId>org.jboss.logging</groupId>
         <artifactId>jboss-logging</artifactId>
         <scope>provided</scope>
      </dependency>
      <!-- Add the jboss-logging-tools processor if you are using JBoss Tools  -->
      <dependency>
         <groupId>org.jboss.logging</groupId>
         <artifactId>jboss-logging-processor</artifactId>
         <scope>provided</scope>
      </dependency>
  3. maven-compiler-plugin のバージョンは 3.1 以上であり、1.8 のターゲットソースおよび生成されたソースに対して設定する必要があります。

    <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-compiler-plugin</artifactId>
       <version>3.1</version>
       <configuration>
          <source>1.8</source>
          <target>1.8</target>
       </configuration>
    </plugin>
注記

JBoss Logging Tools を使用するよう設定された pom.xml ファイルの完全な例は、JBoss EAP に同梱される logging-tools クイックスタートを参照してください。

4.5.7.2. 翻訳プロパティーファイルの形式

JBoss Logging Tools でのメッセージの翻訳に使用されるプロパティーファイルは標準的な Java プロパティーファイルです。このファイルの形式は、java.util.Properties クラスドキュメンテーションに記載されている単純な行指向の key=value ペア形式です。

ファイル名の形式は次のようになります。

InterfaceName.i18n_locale_COUNTRY_VARIANT.properties
  • InterfaceName は翻訳が適用されるインターフェースの名前です。
  • localeCOUNTRY、および VARIANT は翻訳が適用される地域設定を識別します。
  • localeCOUNTRY は ISO-639 および ISO-3166 言語および国コードを使用して言語と国を指定します。COUNTRY は任意です。
  • VARIANT は特定のオペレーティングシステムまたはブラウザーのみに適用される翻訳を識別するために使用できる任意の識別子です。

翻訳ファイルに含まれるプロパティーは翻訳されるインターフェースのメソッドの名前です。プロパティーに割り当てられた値が翻訳になります。メソッドがオーバーロードされる場合、これはドットとパラメーターの数を名前に付加することによって示されます。翻訳のメソッドは、異なる数のパラメーターを提供することによってのみオーバーロードできます。

例: 翻訳プロパティーファイル

ファイル名: GreeterService.i18n_fr_FR_POSIX.properties

# Level: Logger.Level.INFO
# Message: Hello message sent.
logHelloMessageSent=Bonjour message envoyé.

4.5.7.3. JBoss Logging Tools のアノテーションに関するリファレンス

JBoss Logging では、ログメッセージや文字列、例外の国際化や現地語化に使用する以下のアノテーションが定義されています。

表4.2 JBoss Logging Tools のアノテーション

アノテーションターゲット説明属性

@MessageBundle

インターフェース

インターフェースをメッセージバンドルとして定義します。

projectCode

@MessageLogger

インターフェース

インターフェースをメッセージロガーとして定義します。

projectCode

@Message

方法

メッセージバンドルとメッセージロガーで使用できます。メッセージバンドルでは、現地語化された String または Exception オブジェクトを返すメソッドとして定義されます。メッセージロガーでは、現地語化されたロガーとしてメソッドが定義されます。

value, id

@LogMessage

方法

メッセージロガーのメソッドをロギングメソッドとして定義します。

level (デフォルトは INFO)

@Cause

パラメーター

ログメッセージまたは他の例外が発生したときに例外を渡すパラメーターとして定義します。

-

@Param

パラメーター

例外のコンストラクターへ渡されるパラメーターとして定義します。

-

4.5.7.4. JBoss EAP で使用されるプロジェクトコード

以下の表は、 JBoss EAP 7.2 で使用されるすべてのプロジェクトコードとそのプロジェクトコードが属する Maven モジュールの一覧です。

表4.3 JBoss EAP で使用されるプロジェクトコード

Maven モジュールプロジェクトコード

appclient

WFLYAC

batch/extension-jberet

WFLYBATCH

batch/extension

WFLYBATCH-DEPRECATED

batch/jberet

WFLYBAT

bean-validation

WFLYBV

controller-client

WFLYCC

controller

WFLYCTL

clustering/common

WFLYCLCOM

clustering/ejb/infinispan

WFLYCLEJBINF

clustering/infinispan/extension

WFLYCLINF

clustering/jgroups/extension

WFLYCLJG

clustering/server

WFLYCLSV

clustering/web/infinispan

WFLYCLWEBINF

connector

WFLYJCA

deployment-repository

WFLYDR

deployment-scanner

WFLYDS

domain-http

WFLYDMHTTP

domain-management

WFLYDM

ee

WFLYEE

ejb3

WFLYEJB

embedded

WFLYEMB

host-controller

WFLYDC

host-controller

WFLYHC

iiop-openjdk

WFLYIIOP

io/subsystem

WFLYIO

jaxrs

WFLYRS

jdr

WFLYJDR

jmx

WFLYJMX

jpa/hibernate5

JIPI

jpa/spi/src/main/java/org/jipijapa/JipiLogger.java

JIPI

jpa/subsystem

WFLYJPA

jsf/subsystem

WFLYJSF

jsr77

WFLYEEMGMT

launcher

WFLYLNCHR

legacy/jacorb

WFLYORB

legacy/messaging

WFLYMSG

legacy/web

WFLYWEB

logging

WFLYLOG

mail

WFLYMAIL

management-client-content

WFLYCNT

messaging-activemq

WFLYMSGAMQ

mod_cluster/extension

WFLYMODCLS

naming

WFLYNAM

network

WFLYNET

patching

WFLYPAT

picketlink

WFLYPL

platform-mbean

WFLYPMB

pojo

WFLYPOJO

process-controller

WFLYPC

protocol

WFLYPRT

remoting

WFLYRMT

request-controller

WFLYREQCON

rts

WFLYRTS

sar

WFLYSAR

security-manager

WFLYSM

security

WFLYSEC

server

WFLYSRV

system-jmx

WFLYSYSJMX

threads

WFLYTHR

transactions

WFLYTX

undertow

WFLYUT

webservices/server-integration

WFLYWS

weld

WFLYWELD

xts

WFLYXTS