ふたつの川うるおう日記
古いサーバでJDK 6 Update 18に更新したらタイムゾーンがJSTからGMTに変わった件と対処法
- 2010-01-20 (水)
- Unkown
-
とある古いサーバにインストールされているJDK 6 Update 17をJDK 6 Update 18に更新したらデフォルトのタイムゾーンがJSTからGMTに変わってしまいました。他のサーバでは問題なかったのでこの古いサーバ限定の問題です。
状況を確認するためにサンプルコードを動かして確認しました。
import java.util.Date;
public class DateTest {
public static void main(String[] args) {
System.out.println(new java.util.Date());
}
}
実行してみます。
# /usr/local/java/jdk1.6.0_17/bin/java DateTest Wed Jan 20 21:42:44 JST 2010 # /usr/local/java/jdk1.6.0_18/bin/java DateTest Wed Jan 20 12:42:56 GMT 2010
というようにJDK 6 Update 17ではJSTなのにJDK 6 Update 18だとGMTになってしまいました。JVMのタイムゾーンがGMTになる 追記と同じ原因のようで、/etc/localtime を調べてみたら /usr/share/zoneinfo/Asia/Tokyo と違うものでした。
# ls -al /etc/localtime -rw-r--r-- 1 root root 73 Feb 26 2004 /etc/localtime # ls -al /usr/share/zoneinfo/Asia/Tokyo -rw-r--r-- 2 root root 125 Mar 22 2006 /usr/share/zoneinfo/Asia/Tokyo
というわけで、コピーして直します。
cp -a /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
再び確認します。
# /usr/local/java/jdk1.6.0_17/bin/java DateTest Wed Jan 20 21:49:58 JST 2010 # /usr/local/java/jdk1.6.0_18/bin/java DateTest Wed Jan 20 21:50:07 JST 2010
無事直りました。良かった良かった。
/etc/localtime が食い違ってのは、/etc/localtimeのタイムスタンプが2004-02-26 という古いサーバなので、インストール時に何かミスったか、これまでの運用の中での更新で何かがおきたのかなと思います。ただ、JDK更新したらいきなしWEBアプリが書き込むデータのタイムスタンプが9時間ずれ初めてたのでビックリしました。
Cubbyのアクションクラスで定数を利用してリファクタリングしやすくする
Cubbyのアクションクラスにはバリデーションルールの定義時やアノテーションに文字列が登場します。文字列で指定しているのでリファクタリングする時に修正漏れなどがおきそうでちょっと怖いです。そこで、それらの文字列を定数にしてしまえば、少しだけリファクタリングしやすくなりそうです。また、IDE上での参照元・参照先への移動や使われているかどうかのチェックも簡単になります。
例えば、次のようなアクションクラスがあるとします。
@Path("hoge")
public class HogeAction extends AbstractAction {
@Binding(bindingType = BindingType.NONE)
protected ValidationRules processApplyValidation =
new DefaultValidationRules() {
@Override
public void initialize() {
add("token", new TokenValidator());
add("name", new TokenValidator());
add("comment", new TokenValidator());
}
};
@RequestParameter
public HogeParameterDto hogeParameterDto;
@Path("process")
@Accept(POST)
@OnSubmit("apply")
@Form("hogeParameterDto")
@Validation(rules = "processApplyValidation", errorPage = "/hoge/edit.html")
public ActionResult processApply() {
return new Forward("/hoge/edit.html");
}
}
これを次のようにします。
import static org.example.test.entity.names.Names.*;
@Path("hoge")
public class HogeAction extends AbstractAction {
private static final String processApplyValidationName
= "processApplyValidation";
@Binding(bindingType = BindingType.NONE)
protected ValidationRules processApplyValidation =
new DefaultValidationRules() {
@Override
public void initialize() {
add(TOKEN, new TokenValidator());
add(post().name().toString(), new TokenValidator());
add(post().comment().toString(), new TokenValidator());
}
};
private static final String hogeParameterDtoName = "hogeParameterDto";
@RequestParameter
public HogeParameterDto hogeParameterDto;
@Path("process")
@Accept(POST)
@OnSubmit("apply")
@Form(hogeParameterDtoName)
@Validation(rules = processApplyValidationName, errorPage = "/hoge/edit.html")
public ActionResult processApply() {
return new Forward("/hoge/edit.html");
}
}
変更した箇所を説明します。
Cubbyでアクションメソッドに指定するアノテーションの順番
しばらく時間が空いてからCubbyを使ったWEBアプリケーションを書く時に、アクションメソッドに指定するアノテーションの順番どうだったかなっと考えるのでまとめます。アノテーションなので適当な順番に書いても問題なく動作しますが、処理の流れを考えて次の順番で指定しています。
- URIを指定: @Path
- HTTPメソッドを指定: @Accept
- 同一URIへのPOST時などに実行するアクションメソッドを変える指定: @OnSubmit
- リクエストパラメータのバインド先を指定: @Form
- リクエストパラメータのバリデーションを指定: @Validation
@Path("hoge")
public class HogeAction extends AbstractAction {
...
@Path("process")
@Accept(POST)
@OnSubmit("apply")
@Form("hogeParameterDto")
@Validation(rules = "processApplyValidation", errorPage = "/hoge/edit.html")
public ActionResult processApply() {
return new Forward("/hoge/edit.html");
}
...
}
JIRA 4.xと新しいPlugin機構
Seasarプロジェクトでも利用しているJIRA のライセンスを去年の10月に自分用に購入しました。JIRAを開発しているAtlassian社が10ユーザまで利用できるGet Started for $10というライセンスを始めたので思わず買いました。JIRA 4.0になって、JIRA 3.x以前にあったエディションの違いが無くなり、$10でEnterpriseエディションが使えるというのは破格です。JIRA 3.xまではLDAPサポートにEnterprise以上が必要でとても買える金額では無かったため嬉しいです。また、このライセンスの購入費用は全額 Room to Read に寄付されるプログラムになっています。
日本円で購入したい場合は、Atlassian社のOfficial Atlassian Partnerである リックソフト株式会社 が1,050 円で販売されています。
- Bug Tracking, Issue Tracking & Project Management Software – JIRA (Atlassian社)
- アトラシアン(Atlassian)製品の価格と購入(オンライン販売) (リックソフト株式会社)
そんなわけで、だいぶ前置置きが長くなりましたが、自分用にJIRAの環境を作りました。購入当初JIRA 4.0には 新しく導入されたガジェットの仕組みがSSL環境で上手く動かない問題 があったので、使い始めたのはこの問題がJIRA側で解決した4.0.1からです。
ただ、まだ問題があって、Seasarプロジェクトで利用していた3.xのインストール手順でwarファイルを作成し、Tomcatにデプロイするとエラーがでて上手く起動しないのです。いろいろ試してみると自分で追加していたPluginを全部外すと起動しました。そんなことをつぶやいていたらリックソフトのohnukiさんがコンタクトをくださっていろいろやりとりした結果、原因が判明しました。
原因は、JIRA 4.0からOSGiを使用した新しいPlugin機構(Version 2)がサポートされ、JIRA 3.xの時とPluginの配置の仕方が変わっていたことでした。これに気付かず、JIRA 3.xの導入の仕方で入れていたので上手くPluginがロードされなかったようです。一応、互換性のため、古いPluginの配置方法(Version 1)も使えるようですが、Tomcat 5.5.28では動作するものの、Tomcat 6.0.20では動作せず、それでエラーが出ていました。
- 参考: Managing JIRA’s Plugins
- Version 1: atlassian-jira/WEB-INF/lib/ 以下に配置
- Version 2: jira.home/plugins/installed-plugins/ 以下に配置
- jira.home はJIRA 4.0から導入されたホームディレクトリ指定
というわけで、無事やっとPluginも使えるようになりました。ohnukiさんありがとうございました!
Pluginが使えるようになったので、SeasarプロジェクトのJIRAも近日アップグレードのテストをし、アナウンスを出した後に現在の3.13.5から4.0.1に更新したいと思います。
以下、何かの参考までにVersion 1 + Tomcat 6.0.20で起動した時の例外全文を記載しておきます。
WP FreeStyle Wiki 0.1
tDiaryからWordPressに乗り換え、これから書いていくのに標準のエディタで書くのがどうしても面倒だったので、一番慣れ親しんでいるFreeStyle Wikiの記法で書けるPlugin、WP FreeStyle Wikiを作りました。作ったといってもかなりの強引なことをしていてFreeStyle Wikiを丸ごと中で持っており、そこへ外部コマンドで投げてレンダリングしているだけです。
これは、大晦日の31日にWordPress Pluginをなんとなく見ていたところ、makotokwさん(ありがとうございます!)が作られているPukiWiki for WordPressというPluginを見つけて、ソースを見てみたらPukiWikiを丸ごと中に持っていてそんな手があったかと、そのまま勢いで年が明ける前にFreeStyle Wiki用に改造したものです。
以下に置いてありますので使いたい方がいましたらご自由にお使いください。ライセンスは中に持っているFreeStyle Wikiと同じGPLです。
- [2010-01-01]: WP FreeStyle Wiki 0.1
- 最初のリリース、FreeStyle Wiki 3.6.3内蔵、そのうち中身を整理してPlugin Directoryに登録するかもしれません
- [2010-01-01]: WP FreeStyle Wiki 0.1.1 リリース
- Kenichi Maehashiさんからいただいたパッチを適用しました
記法サンプル
以下、記法のサンプルです。 [fswiki] と [/fswiki] で囲んだ部分がFreeStyle Wikiで処理されます。
tDiaryからWordPressへ
- 2010-01-01 (金)
- Diary
-
新年を向かえtDiaryからWordPressへ乗り換えました。
最近WordPressで何かすることが多いので自分のところもWordPressにしました。tDiaryではWikiスタイル + 適当な書き方で書いていたので、自分の書き方に併せて移行するスクリプトを書きました。移行漏れなどまだ一部不具合があるかもしれませんがちょくちょく直していきます。
DellのサーバマシンのBIOS設定をLinux上から行う方法
- 要約: activateCmosToken 0xXXXX でDellのサーバマシンのBIOS設定は変えられます (但し、サポート外)
既に CentOS 5.x をインストール済みの Dell PowerEdge 830 サーバで、OS上でメモリがなぜか256MBしか認識されていませんでした。何か壊れてるのかと思い、既にインストールしてあったDell提供のサーバ管理ソフトウェア OpenManage でハードウェア情報を確認してみると、1GBのメモリが2枚認識されており、合計2GBと表示されていました。
そこで調べてみるとDellのサーバマシンのBIOSには、巨大なメモリが見えるとインストールが失敗するようなOSインストール用に OS Install Mode という設定があり、これが Enable になっているとメモリが256MBしか見えないようにハード的に制約を加えるようです。
というわけで、BIOSの設定を変えれば良いことが判りました。でも、このサーバは遠隔地に置いてあって、現地に行くのがちょっと大変です。こういう時にリモートKVMが使える別売りのDell Remote Access Controller(DRAC)が入っていれば、BIOS画面を直に見ながら簡単に設定できるのですが、残念ながらこのマシンにはDRACは入っていませんでした。というわけで、Linux上からBIOSの設定を変えられないのかなと調べたら変えられました。方法としては次の2つあります。
- OpenManage 上のBIOS設定で変更
- smbios に含まれるコマンドで変更
1は、WEB UIから設定する方法ですが、設定できる項目に限りがありました。基本的な項目以外は設定できないと思って良いでしょう。今回設定を変えたかった OS Install Mode も設定できませんでした。以下に、PowerEdge 830 で設定可能な項目と設定されていた値を記しておきます。
- 一般
- Num Lock: オン
- Diskette: 自動
- NIC: PXE で有効
- USB: BIOS サポートありで有効
- IDE: 自動
- Boot Sequence: デバイスリスト
- Speaker: オン
- CPU Logical Processor (HyperThreading): 有効
- AC Power Recovery Mode: 最終
- Embedded SATA Controller: ATA
- SATA Port 0: 自動
- SATA Port 1: 自動
- SATA Port 2: オフ
- SATA Port 3: オフ
- IDE Primary Drive 0: 自動
- IDE Primary Drive 1: オフ
- Demand-Based Power Management: 無効
- シリアル通信
- Serial Port 1: 不明
- Console Redirection After Boot: 有効
- Console Redirection: シリアルポート 1
- Console Redirection Failsafe BAUD Rate: 19200
OpenManage はyumで簡単にインストールできるので、上記で設定した項目があれば、OpenManage で設定するのが良いと思います。
2は、コマンドラインから設定する方法です。smbios と libsmbios は、OpenManage を入れると一緒にインストールされるDellのサーバマシンのBIOSにアクセスするためのユーティリティ群です。
こちらはおそらくDellのサーバマシンに用意されているBIOSの設定項目すべてを設定できるのだと思います。ただし、BIOSの設定を変える activateCmosToken というコマンドは Unsupported Binaries に分類されています。従って、この記事を読んで設定したらBIOSが壊れてマシンが起動しなくなることもあるかもしれません。そうなっても自分で責任とれる方以外は絶対に行わない方が良いでしょう。
というわけで、設定の仕方です。設定を行うのはactivateCmosToken コマンドを使います。基本構文は次のとおりです。
# /usr/sbin/activateCmosToken 0x"Token Value"
Token Valueというのは、BIOS設定の項目とというる値に対してユニークに割り振られている値になります。Token Valueの一覧は以下にあります。先頭の項目がToken Valueになります。
見てみれば判りますが、よくあるBIOS設定項目、最新の技術に関する設定項目、そして、Dell独自の設定項目があります。
現在の値を確認するには、isCmosTokenActive コマンドを使います。activateCmosToken 同様、引数に 0x"Token Value" を取ればいいだけです。出力の BITFIELD が 1 の場合、それが有効になっているという意味です。
では具体的に OS Install Mode を設定を変え、設定が変わっているか確認します。Token Value List より、OS Install Mode のとりうる値は Enable と Disable の2つで、それぞれに 0×008a と 0×008b の Token Value が割り当てられています。片方の Token Value に対して activateCmosToken を実行すると、もう片方の Token Value の BITFIELD が無効を示す 0 に自動的に変わります。
- Limit System Memory (OS Install Mode) を無効化する方法
# /usr/sbin/activateCmosToken 0x008b DMI type 0xd4 Handle 0xd401 Index Port 0x70 Data Port 0x71 Type 0x008b Location 0x55 AND(fe) OR(0) BITFIELD: 1 # /usr/sbin/isCmosTokenActive 0x008a Running... DMI type 0xd4 Handle 0xd401 Index Port 0x70 Data Port 0x71 Type 0x008a Location 0x55 AND(fe) OR(1) BITFIELD: 0 # /usr/sbin/isCmosTokenActive 0x008b Running... DMI type 0xd4 Handle 0xd401 Index Port 0x70 Data Port 0x71 Type 0x008b Location 0x55 AND(fe) OR(0) BITFIELD: 1
- Limit System Memory (OS Install Mode) 有効化する方法
# /usr/sbin/activateCmosToken 0x008a DMI type 0xd4 Handle 0xd401 Index Port 0x70 Data Port 0x71 Type 0x008a Location 0x55 AND(fe) OR(1) BITFIELD: 1 # /usr/sbin/isCmosTokenActive 0x008a Running... DMI type 0xd4 Handle 0xd401 Index Port 0x70 Data Port 0x71 Type 0x008a Location 0x55 AND(fe) OR(1) BITFIELD: 1 # /usr/sbin/isCmosTokenActive 0x008b Running... DMI type 0xd4 Handle 0xd401 Index Port 0x70 Data Port 0x71 Type 0x008b Location 0x55 AND(fe) OR(0) BITFIELD: 0
以上です。設定はマシンを再起動すると反映されます。
実際に上記の OS Install Mode を無効化する方法で実際に設定しました。その結果、次のように正常にメモリ2GB認識されるようになりました。
- 設定前
# free
total used free shared buffers cached
Mem: 252164 232364 19800 0 9264 129620
-/+ buffers/cache: 93480 158684
Swap: 2097144 236 2096908
- 設定後
# free
total used free shared buffers cached
Mem: 2059368 220968 1838400 0 10396 134724
-/+ buffers/cache: 75848 1983520
Swap: 2097144 0 2097144
無事、サーバのある現地に行くことなく、BIOS設定を変えることができました。遠隔地にあるサーバマシンのBIOS設定をどうしてもリモートで変えたい場合は、試してみると良いかもしれません。ただし、サポート外の方法ですので、BIOSが壊れて起動しなくなるかもしれないことは覚えておいてくださいね!
仮想化環境をテストする環境
最近XenとKVMのHVM環境を比較して試していますが、これまで1台のマシン環境を毎回壊して作り直していました。これが毎回面倒なため、現在、他の用途だったマシンを2台潰して再構築しています。
仮想化環境をテストするのに、PVM環境をテストするなら適当な仮想化環境上(例: VMwareの上でXen PVM環境)で問題ないものの、HVM環境をテストするにはVT対応のCPUが載った実機が必要になるので面倒です。最近のCPUでないとVT対応していないし、VMをたくさん動かすにはメモリもたくさん必要で、そこらへんに余ってる古いマシンで試せず困りものです。
最終的にあと2台用意してXenとKVMを2ノードづつ計4台の環境にしたいものの残り2台をどうしようかな。
XenからKVMへ、ファイルからLVMへ
この日記が動いてるサーバはまだXenですが、新しく仮想マシンをたくさん作る機会があったので、XenからKVMに乗り換えました。OSはdebootstrapになっていますが、virt-installで強引なことしているのでDebianじゃなくてCentOSに入れ替わっています。
# gnt-instance list Instance Hypervisor OS Primary_node Status Memory admin1.example.org kvm debootstrap node1.example.org running 1.0G admin2.example.org kvm debootstrap node2.example.org running 1.0G cron1.example.org kvm debootstrap node1.example.org running 1.0G db1.example.org kvm debootstrap node1.example.org running 1.0G ftp1.example.org kvm debootstrap node2.example.org running 512M irc1.example.org kvm debootstrap node1.example.org running 512M lvs1.example.org kvm debootstrap node2.example.org running 512M lvs2.example.org kvm debootstrap node1.example.org running 512M mail1.example.org kvm debootstrap node1.example.org running 1.0G mail2.example.org kvm debootstrap node2.example.org running 1.0G nouse.example.org kvm debootstrap node2.example.org ADMIN_down - template.example.org kvm debootstrap node1.example.org ADMIN_down - web1.example.org kvm debootstrap node2.example.org running 1.0G web-ssl1.example.org kvm debootstrap node1.example.org running 1.0G web-ssl2.example.org kvm debootstrap node2.example.org running 1.0G
ディスクイメージもファイルからLVMへ乗り換えました。I/O的にも早くなりましたし、1仮想マシンに1LV割り当てたのでライブマイグレーションも出来るようになりました。
# cat /proc/drbd
version: 8.3.2 (api:88/proto:86-90)
GIT-hash: dd7985327f146f33b86d4bff5ca8c94234ce840e build by mockbuild@v20z-x86-64.home.local, 2009-08-29 14:07:55
1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----
ns:1030228 nr:0 dw:1030228 dr:515856 al:499 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
2: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r----
ns:0 nr:684592 dw:684592 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
3: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----
ns:282556 nr:0 dw:282556 dr:432780 al:226 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
4: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r----
ns:0 nr:594628 dw:594628 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
5: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----
ns:281224 nr:0 dw:281224 dr:433112 al:242 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
6: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r----
ns:0 nr:281116 dw:281116 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
7: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----
ns:281048 nr:0 dw:281048 dr:432008 al:227 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
8: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r----
ns:0 nr:283900 dw:283900 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
9: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----
ns:286256 nr:0 dw:286256 dr:430084 al:242 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
10: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r----
ns:0 nr:281384 dw:281384 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
11: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----
ns:306608 nr:0 dw:306608 dr:532548 al:286 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
13: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----
ns:681680 nr:0 dw:681680 dr:823276 al:468 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
14: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r----
ns:0 nr:571076 dw:571076 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
100: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----
ns:48640 nr:0 dw:48640 dr:217 al:23 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
101: cs:Connected ro:Secondary/Secondary ds:UpToDate/UpToDate C r----
ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:188
今回KVMを使ってみて、XenとKVMでは、ホストマシン上でのCPU(uptime)とメモリ(free)の表示が違っていることに気付きました。
Xenを使った時のuptimeの表示は、ホスト側も特殊なDom0 Kernelなのでゲスト側でCPUに負荷が掛かってもホスト側のuptimeにその負荷具合が反映されませんでした。一方、KVMの場合はゲストマシンは1プロセスとして見えるので、ゲスト側に負荷を与えるとホスト側のuptimeの表示に負荷具合が反映されました。
Xenを使った時のfreeの表示は、dom_mem0を指定していない場合、割り当てたメモリ分だけtotalの値が減り、ホスト側では見えなくなります。一方、KVMの場合は起動時に指定したメモリを上限とし、実際にゲスト上でメモリが使用されるとホスト側のfreeが消費されてusedが増えていき、totalの値は常に物理メモリの量のままでした。つまり常に動的なバルーン機能が働いているような状態。もしくは、Sparseファイルのメモリ版のような状態。
どちらが良いかは好みですが、ホスト側で状況を把握できるKVMの方が良い気がしています。あと、最近はXenよりKVMが推されているようなので今後はXenとKVMどちらでも良い場合はKVMを使っていこうと思っています。
- 検索
- フィード
- メタ情報






