今週はjava.util.loggingパッケージ、つまりLogging APIの変更点について紹介します。とはいっても、違いは1点だけです。
Logging APIでログを取るにはjava.util.logging.Loggerクラスを使用します。通常、ログは適切な名前空間により区別されます。名前空間によって区別されたLoggerオブジェクトはLogger.getLogger(name)メソッドで取得することができます。
とはいうものの、簡易的にログを取るためにグローバルで使用できるグローバルロガーも提供されています。
グローバルロガーはJ2SE 5.0までは、static変数globalをそのまま使うことができました。
// J2SE 5.0 での記述法 Logger globalLogger = Logger.global;
ところが、Java SE 6ではこの使い方はDeprecatedになってしまいました。この理由として、Logger.globalの初期化時にデッドロックが発生する可能性があるというのです。
その代わり、グローバルロガー用の名前空間用の名前が新たに導入されました。したがって、グローバルロガーの取得は次のように行ないます。
Logger globalLogger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
GLOBAL_LOGGER_NAMEが新たに導入されたグローバルロガーの名前です。
ところが、これが筆者にはちょっと解せないのです。J2SE 5.0ではglobalは次のように定義されていました。
※ J2SE 5.0のソース public static final Logger global = getLogger("global");
それがJava SE 6では次のように変更されています。
※ Java SE 6のソース public static final Logger global = new Logger(GLOBAL_LOGGER_NAME);
一方のGLOBAL_LOGGER_NAMEは次のように定義されています。
public static final String GLOBAL_LOGGER_NAME = "global";
つまり、Java SE 6のLogger.getLogger(GLOBAL_LOGGER_NAME)は、J2SE 5.0のLogger.globalとまったく同一なのです。
getLoggerメソッドはsynchronizedになっていますが、Loggerのコンストラクタはsynchronizedにはなっていません。つまり、わざわざglobalをnew Logger(GLOBAL_LOGGER_NAME)とすることによりデッドロックする可能性を作ってしまったのではないかと筆者は思うわけです。
筆者はstaticなのにglobalという小文字の変数であることが、変更の理由ではないかと勘ぐっているのですが、真相はどうなのでしょう?
まぁ、変ってしまったものはしかたがありません。Java SE 6ではLogger.globalを使わずに、Logger.getLogger(GLOBA_LOGGER_NAME)を使うようにしましょう。
著者紹介 櫻庭祐一 横河電機 ネットワーク開発センタ所属。Java in the Box 主筆 今月の櫻庭食欲の秋、読書の秋、スポーツの秋と秋は何をするにも最適な季節です。そして、秋はイベントの季節でもあります。 櫻庭が幹事をしている日本Javaユーザグループ(JJUG)でも11月6日にクロスコミュニティカンファレンスを開催します。場所は東京国際フォーラム、参加費は無料です。 また、11月6日から8日までSun Tech Days 2007 in Tokyoが同じく東京国際フォーラムで開催されます。基調講演はJavaの父 James Gosling氏。これは聞き逃せません。 みなさまお誘いあわせの上、ぜひご参加ください。 |