Oracleで「ORA-01882」が出たので対処した

障害内容

あるJavaアプリケーションを実行しようとしたら以下の例外が発生。

java.sql.SQLException: ORA-00604: 再帰SQLレベル1でエラーが発生しました。
ORA-01882: タイムゾーンのリージョンが見つかりません。

環境

OS
Red Hat Enterprise Linux Server release 5 (Tikanga)

先に結論

OSのタイムゾーンが変な値に設定されているので、「/usr/sbin/timeconfig」でタイムゾーンを変更。

結論に至るまでの過程。。。

まずはGoogle先生に聞いてみた。

共にオラクル社カスタマ・サポート・センターに問い合わせないと解決しないエラーです。
サポート契約してサポート・センターに連絡してください。

http://www.oracle.co.jp/forum/thread.jspa?threadID=3001706

連絡とかしてられないので自力で調べる。
とりあえず「date」コマンド実行

[yamap@xxxx ~]$ date
2012年  2月 29日 水曜日 08:49:26 SYOT

実行時の時間は14:49だったので6時間のずれ。
他のredhat環境でコマンド実行すると最後の文字列が「JST」となっていたので、
やっぱりOSのタイムゾーンがおかしい事が原因っぽい。

設定方法をGoogle先生に質問して実行。

Linux で、システムのタイムゾーンを設定する方法
http://perltips.twinkle.cc/server/linux_set_timezone.php

[root@xxxx ~]# mv /etc/localtime /etc/localtime.org
[root@xxxx ~]# ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

「date」コマンドの結果は直ってた。

[yamap@xxxx ~]$ date
2012年  2月 29日 水曜日 15:00:13 SYOT

が、javaから実行すると同じ障害発生。
javaだとタイムゾーンが変更されてない?って事で試す。

System.out.println(System.getProperty("user.timezone"));
[yamap@xxxx ~]# java Test
Antarctica/Syowa

残念。

更に検索したら「/usr/sbin/timeconfig」でタイムゾーンを変更できるとの記述を発見。

Q タイムゾーンを設定するには
http://tooljp.com/linux/faq/EC7B8AFE495087BE492575400061F3F9.html

設定後にjava、アプリケーションで確認したら例外でませんでした。

余談

直接は関係ないですがgroovyで実行した時とjavaで実行した時の結果が違ったのでだいぶはまった。

上記の流れで、javaで実行時に「Antarctica/Syowa」が出てた時に実行。

groovy:000> println System.getProperty("user.timezone")
Asia/Tokyo

groovyはどこからタイムゾーンを設定してるんだろう?
ちなみに、groovyのコードをコンパイルして実行すると空文字が表示されました。
(正しく動作していると思われる環境で実行しても空文字。)