最近では64bit OS環境が広く利用されている事と思います。
一般的に64bit環境での32bitコマンドの実行は問題が無いと思いますが、java関係で二つ程問題が発生したので記録しておきます。
■Tomcatが起動出来なくなった。
64bit => 32bit javaに変更した所、Tomcatが起動しなくなりました。調べてみるとTomcat本体の問題では無かったのですが、jsvcを利用して起動している為、問題が発生しているようです(TOMCAT_HOME/bin/startup.sh等では問題なく起動しました)。
一部推測混じりですが
・jsvcを利用するにはコンパイルが必要
・コンパイル時には、configureを実行
・configureのログをよく見てみると、linux自体を"x86_64"と判定
・よってjavaは64bit版を想定してコンパイルしてしまう(推測)
という理由で上手く行かなくなったのではと思われます。
結論:jsvcを利用する場合は、32/64bitをOSとあわせる必要があります。
■rjb(ruby java bridge)が動かなくなった。
こちらも64bit => 32bit javaに変更した所、動かなくなりました。ruby側からJava VMを作成できなくなるようです。
但し上記問題を解決しても、javaのマイナーバージョン違いで急に動かなくなる場合を確認しています(jdk6u22 => jdk6u23)。ログを見た限りではGC発生タイミングでseg faultしてしまうようです。
リリースノートを見ている限りでは、hotspot vmのバージョンが上がったから?等推測してますが根本原因は判明しませんでした。
結論:rjbを利用する場合は、32/64bitをOSとあわせる必要があります。またマイナーバージョン含め実績のあるjava/rubyのバージョン組み合わせ・設定を大事にする必要があります。
2011年8月20日土曜日
2011年7月27日水曜日
coberturaが猛烈に遅い!...けど解決した
■概要
junitの網羅率測定する為に、coberturaを利用する事が多いと思います。
# 当方久しぶりにjavaを触ったので最近のトレンドにはとんと疎くなりました。もっと良いのがあれば教えてください。
しかしこれが猛烈に遅い!軽快に進めたいのですが、ネックになりそうなので調査しました。
■解説
coberturaの実行はantから行っています。通常
1. コンパイル
2. instrument (coberturaを埋め込む)
3. junit実行
の順番で実行する事になりますが、 3. が非常に遅いのです。
3. の実行は
の様な記載を行うと思いますが、上記だと遅くなってしまいます。
何故なら、antがjunitを起動する際にプロセスのforkを行うのですが、forkはTestCase毎に行われるようです。
複数回のforkを通して網羅率の測定を行う必要がある為、「cobertura.ser」というファイルを
かいして測定を行います。
ところがforkする毎にcobertura.serに、シリアライズ・デシリアライズを行うためのその
オーバーヘッドが大きくなります。実際topコマンド確認するとCPUバウンドな処理である事が分かります。
そこでant 1.6.2より導入された、forkmodeを設定します。
上記の設定により、junitを実行するプロセスは"一度だけ"起動される為、シリアライズ・デシリアライズのオーバーヘッドが無くなり、非常に高速にテストの実行が可能です。
junitの網羅率測定する為に、coberturaを利用する事が多いと思います。
# 当方久しぶりにjavaを触ったので最近のトレンドにはとんと疎くなりました。もっと良いのがあれば教えてください。
しかしこれが猛烈に遅い!軽快に進めたいのですが、ネックになりそうなので調査しました。
■解説
coberturaの実行はantから行っています。通常
1. コンパイル
2. instrument (coberturaを埋め込む)
3. junit実行
の順番で実行する事になりますが、 3. が非常に遅いのです。
3. の実行は
<junit fork="yes" dir="${basedir}">
<classpath location="${instrumented.dir}" />
<classpath location="${classes.dir}" />
<classpath refid="cobertura.classpath" />
<formatter type="xml" />
<test name="${testcase}" todir="${reports.xml.dir}" if="testcase" />
<batchtest todir="${reports.xml.dir}" unless="testcase">
<fileset dir="${src.dir}">
<include name="**/*Test.java" />
</fileset>
</batchtest>
</junit>
の様な記載を行うと思いますが、上記だと遅くなってしまいます。
何故なら、antがjunitを起動する際にプロセスのforkを行うのですが、forkはTestCase毎に行われるようです。
複数回のforkを通して網羅率の測定を行う必要がある為、「cobertura.ser」というファイルを
かいして測定を行います。
ところがforkする毎にcobertura.serに、シリアライズ・デシリアライズを行うためのその
オーバーヘッドが大きくなります。実際topコマンド確認するとCPUバウンドな処理である事が分かります。
そこでant 1.6.2より導入された、forkmodeを設定します。
<junit fork="yes" forkmode="once" dir="${basedir}">
....
上記の設定により、junitを実行するプロセスは"一度だけ"起動される為、シリアライズ・デシリアライズのオーバーヘッドが無くなり、非常に高速にテストの実行が可能です。
2011年6月16日木曜日
gemやmavenで気をつけるべき事
gem(ruby)や、maven(java)を利用し始めると、
「何て便利なんだ!」
と感じると思います。実際非常に便利です。
しかし何年にも渡って運用するようなシステムの場合、「ハード故障に伴うリプレース」や「インフラ移行」が発生する場合があります。
その際に絶対忘れてはいけないのは、
「ライブラリ提供側が、いつまでも場所を提供してくれると考えてはいけない」
という事です。
実際gemで起こった事があるのは、
・githubが提供場所では無くなった(gemcutterへ移行?)
・gems.rubyonrails.orgが提供場所では無くなった(gemcutterへ移行?)
・sqlserverのアダプターの特定のバージョン(1.0.0.9250)が取得できなくなった。
現在は http://rubygems.org/gems/activerecord-sqlserver-adapter/ ですが欲しいバージョンがありません。
と、かなり慌ててしまう状況です。
# さらに性質が悪いのがmaven。
# 私が出くわしたのは「リポジトリはあるがライブラリの該当バージョンが提供されなく無くなった」状況。
# なんと「*.jarの中身をテキストエディタで見ると、503のHTML」。
# しかもエラーを出力しないという難しい状況になります(どのファイルが無くなったのか分からない)
よってgemの場合「cacheディレクトリ以下のgemファイルはちゃんととっておきましょう!」というのが教訓になります。もちろんアプリ側では「versionを絶対指定しておく」というのも大事ですね。
もちろんrailsの場合、vendor配下にコミットしたら良いのでは?という意見もあるかもしれませんが、度々デプロイする場合、純粋にサイズが大きすぎて遅い場合があります。
コンテキストに合わせて最良の方法を考えましょう。
「何て便利なんだ!」
と感じると思います。実際非常に便利です。
しかし何年にも渡って運用するようなシステムの場合、「ハード故障に伴うリプレース」や「インフラ移行」が発生する場合があります。
その際に絶対忘れてはいけないのは、
「ライブラリ提供側が、いつまでも場所を提供してくれると考えてはいけない」
という事です。
実際gemで起こった事があるのは、
・githubが提供場所では無くなった(gemcutterへ移行?)
・gems.rubyonrails.orgが提供場所では無くなった(gemcutterへ移行?)
・sqlserverのアダプターの特定のバージョン(1.0.0.9250)が取得できなくなった。
現在は http://rubygems.org/gems/activerecord-sqlserver-adapter/ ですが欲しいバージョンがありません。
と、かなり慌ててしまう状況です。
# さらに性質が悪いのがmaven。
# 私が出くわしたのは「リポジトリはあるがライブラリの該当バージョンが提供されなく無くなった」状況。
# なんと「*.jarの中身をテキストエディタで見ると、503のHTML」。
# しかもエラーを出力しないという難しい状況になります(どのファイルが無くなったのか分からない)
よってgemの場合「cacheディレクトリ以下のgemファイルはちゃんととっておきましょう!」というのが教訓になります。もちろんアプリ側では「versionを絶対指定しておく」というのも大事ですね。
もちろんrailsの場合、vendor配下にコミットしたら良いのでは?という意見もあるかもしれませんが、度々デプロイする場合、純粋にサイズが大きすぎて遅い場合があります。
コンテキストに合わせて最良の方法を考えましょう。
登録:
投稿 (Atom)

