2009年02月02日(月) [長年日記]
■ [java] NetBeans の Code Coverage Plugin が NullPointerException になる
NetBeans 6.5でカバレッジを取りたいと思い「使用可能なプラグイン」画面で探したら、Code Coverage Plugin(たぶんこれ)というプラグインがあったのでインストールしてみた。
問題点
んが、これをインストールすると「プロジェクト」のツリービューでプロジェクトを右クリックしたときのコンテキストメニューが表示されなくなってしまった。ウィンドウの右下で赤丸が点滅しているのでクリックすると、
java.lang.NullPointerException at org.netbeans.modules.coverage.config.Config.getProjectType(Config.java:163) at org.netbeans.modules.coverage.config.Config.isNbModuleProject(Config.java:188) at org.netbeans.modules.coverage.config.Config.isSupportedProject(Config.java:192) at org.netbeans.modules.coverage.ProjectMenuAction$ProjectContextAwareMenuAction$ProjectMenuItems.<init>(ProjectMenuAction.java:146) at org.netbeans.modules.coverage.ProjectMenuAction$ProjectContextAwareMenuAction.getPopupPresenter(ProjectMenuAction.java:126) at org.openide.util.Utilities.actionsToPopup(Utilities.java:2676) at org.openide.util.Utilities.actionsToPopup(Utilities.java:2756) at org.openide.explorer.view.TreeView.createPopup(TreeView.java:953) at org.openide.explorer.view.TreeView$PopupAdapter.showPopup(TreeView.java:1427) at org.openide.awt.MouseUtils$PopupMouseAdapter.maybePopup(MouseUtils.java:182) at org.openide.awt.MouseUtils$PopupMouseAdapter.mouseReleased(MouseUtils.java:177) at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:273) at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:272) at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:272) at java.awt.Component.processMouseEvent(Component.java:6134) at javax.swing.JComponent.processMouseEvent(JComponent.java:3265) at java.awt.Component.processEvent(Component.java:5899) at java.awt.Container.processEvent(Container.java:2023) at java.awt.Component.dispatchEventImpl(Component.java:4501) at java.awt.Container.dispatchEventImpl(Container.java:2081) at java.awt.Component.dispatchEvent(Component.java:4331) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4301) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3965) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3895) at java.awt.Container.dispatchEventImpl(Container.java:2067) at java.awt.Window.dispatchEventImpl(Window.java:2458) at java.awt.Component.dispatchEvent(Component.java:4331) [catch] at java.awt.EventQueue.dispatchEvent(EventQueue.java:599) at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:104) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
というスタックトレースが表示された。Code Coverage Pluginはプロジェクトを右クリックして設定するようなので、これでは使うことができない。
解決方法
色々いじっていると、右クリックしてもエラーにならずコンテキストメニューが表示されるプロジェクトもあった。
どうやら、「主プロジェクト」に設定したものだけ右クリック時にエラーになるようだ。だから、主プロジェクトを解除する、というのが解決方法。
主プロジェクトの解除は、別のプロジェクトを主プロジェクトにするか、プロジェクトを一旦閉じて開きなおせばできるみたい。
使用感
使えるようになったので試してみたが、あまり便利じゃなかった。
プラグインをActivateした後でテストを実行するとカバレッジが計測されて結果画面にカバレッジ率が表示されるけど、それだけ。結果画面は見難いし、そこからソースコードにジャンプできないようで不便。
■ [java] JMockitでカバレッジ結果の一部が表示されない
Code Coverage Plugin が気に入らなかったので、NetBeans上でカバレッジを計測するのは諦めた。Antに組み込んで計測するのでいいやと思ってカバレッジツールを探すと、
が見つかった。EMMAは2005年、Coberturnalは2007年から更新されていないようだが、JMockitは2008年10月に更新されていたので、JMockitを使ってみることにした。
問題点
頑張って設定し、計測結果のHTMLが出力できて喜んでいたが、よく見るとHTMLに出力されていないクラスがあった。
正しいかどうかわからないけれど、「aaa.bb」「aaa.bbc」のように先頭部分が一致するパッケージがあったときに、「aaa.bbc」の方が結果画面に出力されないみたい。
解決方法は分からない。のでJMockitも諦める。せっかく設定したので設定方法を以下にメモ。
インストール
jmockit-0.95.zip(トップページにあるDownloadのリンクは0.94を指しているので注意)をダウンロードして展開すると、 トップディレクトリにjarファイルが4つある。用途に応じてこれらのうち必要なものをクラスパスに含めればいいのだと思う。
Antに組み込んでカバレッジを測る
JUnitを使ってテストを行うAntターゲットが既にあるとして、その中のjunitタスクに
<jvmarg value="-javaagent:/pathpath/jmockit.jar=coverage=AAA:BBB:CCC:DDD"/>
のようなjvmarg要素を追加すればいいようだった。
- javaagentの後ろにはjmockit.jarへのパスを指定
- coverageの後ろには、classSelectionRegex、outputFormat、outputDir、srcDirsの4つを指定する。コロン区切りで指定するみたい。省略も可能。
- classSelectionRegexで計測対象のクラスを指定するみたいだが、上に書いたように「aaa.*」と指定しても aaa.bbc 配下のクラスはHTMLに出力されなかった(正確に言うと、クラス個別のHTMLファイルは生成されているが、index.htmlに必要なリンクが出力されない)。正規表現を書けるようなので、ここをうまく書けば問題が解決するのかも。
- outputFormatはxml, xml-nocp, html, html-nocpから選べる。nocpの意味はよく分からない。
- outputDirは結果の出力ディレクトリ。
- srcDirsはソースファイルの在処。カンマ区切りで複数書いてみたら認識してくれた。
詳しくは(あまり詳しくもないけど)ドキュメントのHow to run tests with code coverageを参照のこと。
junitタスク自体の書き方にあまり自信がないが、次のような感じで書いていた。クラスパスには jmockit.jar だけでなく coverage.jar も含める必要がある。
<target name="coverage" depends="..."> <junit fork="yes"> <formatter type="plain" usefile="no"/> <classpath> <pathelement location="..."/> </classpath> <jvmarg value="-javaagent:${basedir}/lib/jmockit.jar=coverage=abc.*:html::nantoka/src,kantoka/src"/> <batchtest fork="yes"> <fileset dir="..."> <include name="**/*Test.java"/> </fileset> </batchtest> </junit> </target>
2009年02月03日(火) [長年日記]
- 初めてLinuxでVMWare Playerを使ったが、設定方法がよく分からない。Windowsだとvmnetcfg.exeでネットワークの設定ができるけど、Linuxだとどうすればいいのか。
■ [java] Cobertura でカバレッジを測定した
昨日のJMockitでは十分な結果を得られなかったので、Coberturaを使ってみることにした。こちらは素直に動いた。
インストール
Cobertura 1.9のアーカイブをダウンロードして展開するとトップディレクトリに cobertura.jar というファイルがあり、libディレクトリにもいくつかjarファイルがある。これら全てをクラスパスに含めれば使用できる。
Antに組み込んでカバレッジを測る
junitタスクを既に使っているとして、その前に cobertura-instrument タスクを実行し、junitタスクが完了したら cobertura-report タスクを実行すればいい。次のような感じ。ドキュメントにある通りにすればよい。
<target name="coverage" depends="..."> <delete file="cobertura.ser" /> <!-- 削除が必要みたい --> <path id="cobertura.classpath"> <fileset dir="..."> <include name="cobertura.jar"/> <include name="lib/**/*.jar"/> </fileset> </path> <taskdef classpathref="cobertura.classpath" resource="tasks.properties"/> <cobertura-instrument todir="..."> <fileset dir="..." includes="**/*.class"/> </cobertura-instrument> <junit fork="yes"> <formatter type="plain" usefile="no"/> <classpath> <pathelement location="..."/> <pathelement location="..."/> <pathelement location="..."/> </classpath> <batchtest fork="yes"> <fileset dir="..."> <include name="**/*Test.java"/> </fileset> </batchtest> </junit> <cobertura-report destdir="..."> <fileset dir="nantoka/src/src" includes="**/*.java"/> <fileset dir="kantoka/src" includes="**/*.java"/> </cobertura-report> </target>
2009年02月04日(水) [長年日記]
■ [etc] メイルの管理
職場でメンバーがメイルソフトを操作している場面を見ることがあるが、メイル一覧をスレッド表示している人は皆無。皆フラットにメイルを並べている。高機能メイルソフトを使っているのに、なんでかな。
なので、返信の元になったメイルを見たい時になかなか見つけられなくて滑稽。どうも、返信の元になったメイルを見る、ということはあまりしなくて、引用部分から過去のメイルの内容を読み取ろうとするみたい。だからみんな全文引用するのかも。全文引用の部分なんか読みにくくてやってられないと思うのだけれど。
■ [java] Listの初期化
ArrayListなどの初期化は次のように書けるのでメモ。
package sample; import java.util.ArrayList; import java.util.List; public class ListSample { public static void main(String[] args) { List<String> strings = new ArrayList<String>() { { add("one"); add("two"); add("three"); } }; System.out.println(strings); //=> [one, two, three] } }
ArrayListを継承した無名クラスを作って、その初期化ブロックで要素を追加している。
初期化ブロックはコンストラクタより先に実行されるのでそこでadd()メソッドを呼び出すのは問題があるのでは、と思ったが、add()はスーパークラスのメソッドで、初期化ブロックより先にスーパークラスのコンストラクタが実行されるので、問題はなさそう。
ええと、よく考えると上の例なら
Arrays.asList(new String[] {"one", "two", "three"});
でも実現できてこっちの方が簡潔かも。Mapなら上の書き方が便利なのかなあ。
ああ、今どきは
Arrays.asList("one", "two", "three");
と書けるのであった。
2009年02月05日(木) [長年日記]
- Firefox 3.0.6がリリースされている。Firefoxは自動的にアップデートを通知してくれるから安心だよね、と思っていたら、自宅のFirefoxのバージョンが3.0.4だった。むむむ。どうやら管理ユーザでなく一般ユーザでログインしているとFirefoxの更新通知は機能しないみたい。以前は一般ユーザでも通知してくれていた気がするけどなあ。通知すべきだと思う。危ないので気をつけないと。
- あっ、引越ししてから1年経っていた。早い。新築だったのに汚れてきた。おれのせいなんだなあ。まだ家具が揃っていない。
- だからもう郵便は転送されてこないと。
■ [java][javascript] jrunscriptを使った
JDK6に付属しているjrunscriptを初めて使ったのでメモ。
先週メモしたプロパティファイルを読み込むクラスをjrunscript上で対話的に操作する例。
$ jrunscript -cp class:etc js> var loader = Packages.sample.PropertiesLoader() js> loader.load() {name=oreore, os=CentOS, lang=java} js> quit() $
一応Rubyのirbのように使える。が、Linuxだと(少なくともおれの環境では)履歴を辿ったり補完をしたりすることができず、シェルとして不便すぎてイマイチ使えない。Windowsで動かすと履歴は辿れる。ちなみに、Java DBのijコマンドにも同様の問題がある。
- Javaのクラスにアクセスするには、"トップレベルの変数" らしい Packages から辿る。「java」で始まるパッケージなどは Packages を省略できる。
- 対話モードを終了するには quit() を実行する。括弧を書かないとエラーになるのが面倒。
(追記)
上の実行例をよく見ると、sample.PropertiesLoader のインスタンスを作るときに new と書いていない。書いたつもりだったが。
が、new と書かなくても動くみたい。書いても動く。なんでだ。JavaScriptってそういう仕様なんだっけ?
参考
- Javaプラットフォームのスクリプト (JDK 6 ドキュメント)
- Rhino documentation (Mozilla Developer Center)
- Javascript(Rhino/jrunscript)から Java のリソースを利用する (himorogiの日記)
- 「Java SE 6完全攻略」第58回 Javaでマルチリンガル - スクリプト言語のサポート その1 (IT Pro) 「その11」まである
2009年02月17日(火) [長年日記]
- 昨日まで暑くて今日から寒い。
■ [howto][shell][net] ポートが開いているかをチェックするスクリプト (2)
先月考えたfuserコマンドを使うスクリプトが動作しない環境があった。その環境だと、ポート番号によってはfuserコマンドが出力結果を返してくれない。動かない環境が手元になくて詳しい調査ができず、原因不明。環境の違いは64ビットかどうかくらいだと思う。もしかしたらSELinuxの設定が違うのかもしれない。
仕方ないのでfuserを使わない方法を考えた。netstatコマンドがどうやって空きポートを取得しているのかをソースを読んで調べたところ、/proc/net にある tcp, tcp6, udp, udp6 などを読み込んでいるようだった。ふーん、ここでわかるのか。
しかしシェルスクリプトなら /proc から読み取るより netstat の出力結果から切り出した方が簡単だと思い直し、次のようにして実現した。
if [ -n "`/bin/netstat -ln --tcp | \ /bin/awk '{print $4;}' | \ /bin/grep '^.*:10000$'`" ] ; then echo port is opened. else echo port is closed. fi
これはTCPポート10000が開いているかを調べる例。awkを使うのは富豪的かなあ。
fuserのときのように実行ユーザを気にしたりしなくても大丈夫なはず。ただ、netstatの出力フォーマットに依存するので少し落ち着かない。
2009年02月19日(木) [長年日記]
■ [unix] 自動停止のためには /var/lock/subsys 配下にファイルが必要
CentOS 5での話。デーモンの起動/終了スクリプトを作ってchkconfigで登録し、OS起動時にデーモンが自動起動するようになった。が、OS終了時には自動停止していない。
原因を調べるために /etc/rc を読むと、停止処理内に
[ -f /var/lock/subsys/$subsys -o -f /var/lock/subsys/$subsys.init ] \ || continue
という記述があり /var/lock/subsys ディレクトリ配下にロックファイルがない場合は停止処理を行わないようになっていた。そうなのか。
ロックファイルを作るように起動/終了スクリプトを修正して解決。
■ [unix][dev] GREP_OPTIONS=--color=always にしていたら configure が正しく動かなかった
とあるプログラムのconfigure実行時に
checking whether make sets $(MAKE)... ./configure: line 1618: ac_makeommand not found ./configure: line 1618: 31mtemp=make: command not found
というエラーが表示されているのに気づいた。「ac_makeommand」とか「31mtemp=make」とかどーゆーことか。
1618行目では
eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
という処理が行われていた。evalを使わなければ普通に動くが処理結果をevalに渡すとエラーになる。
grepの処理結果に色が付いていることでピンときた。昨日から環境変数GREP_OPTIONSに「--color=always」を設定するようにしていたのだった。この環境変数の値を「--color=auto」に戻すと、configureはエラーにならなくなった。
grepで --color=always を使うとエスケープシーケンスが色々と悪さをするのでよくない、という話でした。
■ [web][soft] Firefoxが折り返さない
上の日記を書いたら、Firefox 3でここを見た時に右にある「最近の日記」欄から文字がはみ出して横スクロールバーが表示されるようになってしまった。「GREP_OPTIONS=--color=always」の部分を折り返し表示してくれないのが原因。
IE7やOpera 9では大丈夫。
こういうのも折り返さないみたい。
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
えー。これはIEもOperaも折り返さないや。CSSの書き方が悪いのかな。
2009年02月27日(金) [長年日記]
- Javaの仕事はほぼ終了。
- 次はまたC++だと予想していたら、プログラミングではない仕事を受注。テスト作業のような仕事。作業にはツールが必要なので、それをRubyで実装中。
- 久々のRubyは楽しい。RSpecを初めて使ってみた。specを日本語でバリバリ書くぞ。