ラベル java の投稿を表示しています。 すべての投稿を表示
ラベル java の投稿を表示しています。 すべての投稿を表示

2011年8月20日土曜日

javaの32bitと64bitの使い分けにはご注意を

最近では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年7月27日水曜日

coberturaが猛烈に遅い!...けど解決した

■概要

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配下にコミットしたら良いのでは?という意見もあるかもしれませんが、度々デプロイする場合、純粋にサイズが大きすぎて遅い場合があります。
コンテキストに合わせて最良の方法を考えましょう。